From d5ea5d30d8e400b73d2a5abf2d1e2d8fc3485bd6 Mon Sep 17 00:00:00 2001 From: Stefan Esser Date: Sun, 16 Feb 2014 13:05:36 +0100 Subject: Refactor array index handling in input filter, to make it work in all cases. --- Changelog | 1 + ifilter.c | 77 ++++++++++++++++++++++++++++++++++----------------------------- ufilter.c | 41 ++++++++++++++++++++-------------- 3 files changed, 67 insertions(+), 52 deletions(-) diff --git a/Changelog b/Changelog index 9bc62e9..1129c99 100644 --- a/Changelog +++ b/Changelog @@ -11,6 +11,7 @@ - Added suhosin.log.stdout to log to stdout (for debugging purposes only) - Add ini_set() fail mode to suhosin.disable.display_errors - Fix suhosin.get/post/cookie.max_totalname_length filter + - Refactor array index handling in filter to make it work always - TODO: WARN THAT FUNCTION WHITELISTS/BLACKLISTS NEVER WORKED CORRECTLY WITH PHP < 5.5 2012-02-12 - 0.9.34 diff --git a/ifilter.c b/ifilter.c index 42f5d9b..d73106b 100644 --- a/ifilter.c +++ b/ifilter.c @@ -502,49 +502,56 @@ unsigned int suhosin_input_filter(int arg, char *var, char **val, unsigned int v /* Find out array depth */ while (index) { + char *index_end; unsigned int index_length; + /* overjump '[' */ + index++; + + /* increase array depth */ depth++; - index = strchr(index+1, '['); + + index_end = strchr(index, ']'); + if (index_end == NULL) { + index_end = index+strlen(index); + } - if (prev_index) { - index_length = index ? index - 1 - prev_index - 1: strlen(prev_index); + index_length = index_end - index; - if (SUHOSIN_G(max_array_index_length) && SUHOSIN_G(max_array_index_length) < index_length) { - suhosin_log(S_VARS, "configured request variable array index length limit exceeded - dropped variable '%s'", var); - if (!SUHOSIN_G(simulation)) { - return 0; - } - } - switch (arg) { - case PARSE_GET: - if (SUHOSIN_G(max_get_array_index_length) && SUHOSIN_G(max_get_array_index_length) < index_length) { - suhosin_log(S_VARS, "configured GET variable array index length limit exceeded - dropped variable '%s'", var); - if (!SUHOSIN_G(simulation)) { - return 0; - } - } - break; - case PARSE_COOKIE: - if (SUHOSIN_G(max_cookie_array_index_length) && SUHOSIN_G(max_cookie_array_index_length) < index_length) { - suhosin_log(S_VARS, "configured COOKIE variable array index length limit exceeded - dropped variable '%s'", var); - if (!SUHOSIN_G(simulation)) { - return 0; - } - } - break; - case PARSE_POST: - if (SUHOSIN_G(max_post_array_index_length) && SUHOSIN_G(max_post_array_index_length) < index_length) { - suhosin_log(S_VARS, "configured POST variable array index length limit exceeded - dropped variable '%s'", var); - if (!SUHOSIN_G(simulation)) { - return 0; - } - } - break; + if (SUHOSIN_G(max_array_index_length) && SUHOSIN_G(max_array_index_length) < index_length) { + suhosin_log(S_VARS, "configured request variable array index length limit exceeded - dropped variable '%s'", var); + if (!SUHOSIN_G(simulation)) { + return 0; } - prev_index = index; + } + switch (arg) { + case PARSE_GET: + if (SUHOSIN_G(max_get_array_index_length) && SUHOSIN_G(max_get_array_index_length) < index_length) { + suhosin_log(S_VARS, "configured GET variable array index length limit exceeded - dropped variable '%s'", var); + if (!SUHOSIN_G(simulation)) { + return 0; + } + } + break; + case PARSE_COOKIE: + if (SUHOSIN_G(max_cookie_array_index_length) && SUHOSIN_G(max_cookie_array_index_length) < index_length) { + suhosin_log(S_VARS, "configured COOKIE variable array index length limit exceeded - dropped variable '%s'", var); + if (!SUHOSIN_G(simulation)) { + return 0; + } + } + break; + case PARSE_POST: + if (SUHOSIN_G(max_post_array_index_length) && SUHOSIN_G(max_post_array_index_length) < index_length) { + suhosin_log(S_VARS, "configured POST variable array index length limit exceeded - dropped variable '%s'", var); + if (!SUHOSIN_G(simulation)) { + return 0; + } + } + break; } + index = strchr(index, '['); } /* Drop this variable if it exceeds the array depth limit */ diff --git a/ufilter.c b/ufilter.c index efab2ce..67bb114 100644 --- a/ufilter.c +++ b/ufilter.c @@ -131,29 +131,36 @@ static int check_fileupload_varname(char *varname) /* Find out array depth */ while (index) { + char *index_end; unsigned int index_length; + /* overjump '[' */ + index++; + + /* increase array depth */ depth++; - index = strchr(index+1, '['); + + index_end = strchr(index, ']'); + if (index_end == NULL) { + index_end = index+strlen(index); + } - if (prev_index) { - index_length = index ? index - 1 - prev_index - 1: strlen(prev_index); + index_length = index_end - index; - if (SUHOSIN_G(max_array_index_length) && SUHOSIN_G(max_array_index_length) < index_length) { - suhosin_log(S_FILES, "configured request variable array index length limit exceeded - dropped variable '%s'", var); - if (!SUHOSIN_G(simulation)) { - goto return_failure; - } - } - if (SUHOSIN_G(max_post_array_index_length) && SUHOSIN_G(max_post_array_index_length) < index_length) { - suhosin_log(S_FILES, "configured POST variable array index length limit exceeded - dropped variable '%s'", var); - if (!SUHOSIN_G(simulation)) { - goto return_failure; - } - } - prev_index = index; - } + if (SUHOSIN_G(max_array_index_length) && SUHOSIN_G(max_array_index_length) < index_length) { + suhosin_log(S_FILES, "configured request variable array index length limit exceeded - dropped variable '%s'", var); + if (!SUHOSIN_G(simulation)) { + goto return_failure; + } + } + if (SUHOSIN_G(max_post_array_index_length) && SUHOSIN_G(max_post_array_index_length) < index_length) { + suhosin_log(S_FILES, "configured POST variable array index length limit exceeded - dropped variable '%s'", var); + if (!SUHOSIN_G(simulation)) { + goto return_failure; + } + } + index = strchr(index, '['); } /* Drop this variable if it exceeds the array depth limit */ -- cgit v1.3