diff options
| -rw-r--r-- | ex_imp.c | 8 | ||||
| -rw-r--r-- | ifilter.c | 2 | ||||
| -rw-r--r-- | php_suhosin.h | 85 | ||||
| -rw-r--r-- | ufilter.c | 2 |
4 files changed, 73 insertions, 24 deletions
| @@ -74,7 +74,7 @@ static int php_valid_var_name(char *var_name, int len) /* {{{ */ | |||
| 74 | } | 74 | } |
| 75 | } | 75 | } |
| 76 | 76 | ||
| 77 | if (php_varname_check(var_name, len, 1 TSRMLS_CC) == FAILURE) { | 77 | if (suhosin_is_protected_varname(var_name, len)) { |
| 78 | return 0; | 78 | return 0; |
| 79 | } | 79 | } |
| 80 | 80 | ||
| @@ -459,7 +459,7 @@ static int copy_request_variable(void *pDest TSRMLS_DC, int num_args, va_list ar | |||
| 459 | zval_dtor(&num); | 459 | zval_dtor(&num); |
| 460 | } | 460 | } |
| 461 | 461 | ||
| 462 | if (php_varname_check(Z_STRVAL(new_key), Z_STRLEN(new_key), 0 TSRMLS_CC) == FAILURE) { | 462 | if (php_varname_check(Z_STRVAL(new_key), Z_STRLEN(new_key), 1 TSRMLS_CC) == FAILURE || suhosin_is_protected_varname(Z_STRVAL(new_key), Z_STRLEN(new_key))) { |
| 463 | zval_dtor(&new_key); | 463 | zval_dtor(&new_key); |
| 464 | return 0; | 464 | return 0; |
| 465 | } | 465 | } |
| @@ -506,8 +506,8 @@ static int copy_request_variable(void *pDest, int num_args, va_list args, zend_h | |||
| 506 | new_key_len++; | 506 | new_key_len++; |
| 507 | } | 507 | } |
| 508 | 508 | ||
| 509 | if (php_varname_check(new_key, new_key_len-1, 0 TSRMLS_CC) == FAILURE) { | 509 | if (php_varname_check(new_key, new_key_len-1, 1 TSRMLS_CC) == FAILURE || suhosin_is_protected_varname(new_key, new_key_len-1)) { |
| 510 | zval_dtor(&new_key); | 510 | efree(new_key); |
| 511 | return 0; | 511 | return 0; |
| 512 | } | 512 | } |
| 513 | 513 | ||
| @@ -620,7 +620,7 @@ unsigned int suhosin_input_filter(int arg, char *var, char **val, unsigned int v | |||
| 620 | 620 | ||
| 621 | /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */ | 621 | /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */ |
| 622 | /* This is to protect several silly scripts that do globalizing themself */ | 622 | /* This is to protect several silly scripts that do globalizing themself */ |
| 623 | if (php_varname_check(var, var_len, 1 TSRMLS_CC) == FAILURE) { | 623 | if (suhosin_is_protected_varname(var, var_len)) { |
| 624 | suhosin_log(S_VARS, "tried to register forbidden variable '%s' through %s variables", var, arg == PARSE_GET ? "GET" : arg == PARSE_POST ? "POST" : "COOKIE"); | 624 | suhosin_log(S_VARS, "tried to register forbidden variable '%s' through %s variables", var, arg == PARSE_GET ? "GET" : arg == PARSE_POST ? "POST" : "COOKIE"); |
| 625 | if (!SUHOSIN_G(simulation)) { | 625 | if (!SUHOSIN_G(simulation)) { |
| 626 | return 0; | 626 | return 0; |
diff --git a/php_suhosin.h b/php_suhosin.h index e89d02b..b80d9b9 100644 --- a/php_suhosin.h +++ b/php_suhosin.h | |||
| @@ -70,24 +70,74 @@ PHP_MINFO_FUNCTION(suhosin); | |||
| 70 | 70 | ||
| 71 | #include "ext/standard/basic_functions.h" | 71 | #include "ext/standard/basic_functions.h" |
| 72 | 72 | ||
| 73 | static inline int suhosin_is_protected_varname(char *var, int var_len) | ||
| 74 | { | ||
| 75 | switch (var_len) { | ||
| 76 | case 18: | ||
| 77 | if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname; | ||
| 78 | break; | ||
| 79 | case 17: | ||
| 80 | if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname; | ||
| 81 | break; | ||
| 82 | case 16: | ||
| 83 | if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname; | ||
| 84 | if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname; | ||
| 85 | break; | ||
| 86 | case 15: | ||
| 87 | if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname; | ||
| 88 | break; | ||
| 89 | case 14: | ||
| 90 | if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname; | ||
| 91 | break; | ||
| 92 | case 13: | ||
| 93 | if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname; | ||
| 94 | if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname; | ||
| 95 | break; | ||
| 96 | case 8: | ||
| 97 | if (memcmp(var, "_SESSION", 8)==0) goto protected_varname; | ||
| 98 | if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname; | ||
| 99 | break; | ||
| 100 | case 7: | ||
| 101 | if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname; | ||
| 102 | if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname; | ||
| 103 | if (memcmp(var, "_SERVER", 7)==0) goto protected_varname; | ||
| 104 | break; | ||
| 105 | case 6: | ||
| 106 | if (memcmp(var, "_FILES", 6)==0) goto protected_varname; | ||
| 107 | break; | ||
| 108 | case 5: | ||
| 109 | if (memcmp(var, "_POST", 5)==0) goto protected_varname; | ||
| 110 | break; | ||
| 111 | case 4: | ||
| 112 | if (memcmp(var, "_ENV", 4)==0) goto protected_varname; | ||
| 113 | if (memcmp(var, "_GET", 4)==0) goto protected_varname; | ||
| 114 | break; | ||
| 115 | } | ||
| 116 | |||
| 117 | return 0; | ||
| 118 | protected_varname: | ||
| 119 | return 1; | ||
| 120 | } | ||
| 121 | |||
| 122 | |||
| 73 | #if PHP_VERSION_ID < 50203 | 123 | #if PHP_VERSION_ID < 50203 |
| 74 | static inline int php_varname_check(char *name, int name_len, zend_bool silent TSRMLS_DC) /* {{{ */ | 124 | static inline int php_varname_check(char *name, int name_len, zend_bool silent TSRMLS_DC) /* {{{ */ |
| 75 | { | 125 | { |
| 76 | if (name_len == sizeof("GLOBALS") && !memcmp(name, "GLOBALS", sizeof("GLOBALS"))) { | 126 | if (name_len == sizeof("GLOBALS") - 1 && !memcmp(name, "GLOBALS", sizeof("GLOBALS") - 1)) { |
| 77 | if (!silent) { | 127 | if (!silent) { |
| 78 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attempted GLOBALS variable overwrite"); | 128 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attempted GLOBALS variable overwrite"); |
| 79 | } | 129 | } |
| 80 | return FAILURE; | 130 | return FAILURE; |
| 81 | } else if (name[0] == '_' && | 131 | } else if (name[0] == '_' && |
| 82 | ( | 132 | ( |
| 83 | (name_len == sizeof("_GET") && !memcmp(name, "_GET", sizeof("_GET"))) || | 133 | (name_len == sizeof("_GET") - 1 && !memcmp(name, "_GET", sizeof("_GET") - 1)) || |
| 84 | (name_len == sizeof("_POST") && !memcmp(name, "_POST", sizeof("_POST"))) || | 134 | (name_len == sizeof("_POST") - 1 && !memcmp(name, "_POST", sizeof("_POST") - 1)) || |
| 85 | (name_len == sizeof("_COOKIE") && !memcmp(name, "_COOKIE", sizeof("_COOKIE"))) || | 135 | (name_len == sizeof("_COOKIE") - 1 && !memcmp(name, "_COOKIE", sizeof("_COOKIE") - 1)) || |
| 86 | (name_len == sizeof("_ENV") && !memcmp(name, "_ENV", sizeof("_ENV"))) || | 136 | (name_len == sizeof("_ENV") - 1 && !memcmp(name, "_ENV", sizeof("_ENV") - 1)) || |
| 87 | (name_len == sizeof("_SERVER") && !memcmp(name, "_SERVER", sizeof("_SERVER"))) || | 137 | (name_len == sizeof("_SERVER") - 1 && !memcmp(name, "_SERVER", sizeof("_SERVER") - 1)) || |
| 88 | (name_len == sizeof("_SESSION") && !memcmp(name, "_SESSION", sizeof("_SESSION"))) || | 138 | (name_len == sizeof("_SESSION") - 1 && !memcmp(name, "_SESSION", sizeof("_SESSION") - 1)) || |
| 89 | (name_len == sizeof("_FILES") && !memcmp(name, "_FILES", sizeof("_FILES"))) || | 139 | (name_len == sizeof("_FILES") - 1 && !memcmp(name, "_FILES", sizeof("_FILES") - 1)) || |
| 90 | (name_len == sizeof("_REQUEST") && !memcmp(name, "_REQUEST", sizeof("_REQUEST"))) | 140 | (name_len == sizeof("_REQUEST") -1 && !memcmp(name, "_REQUEST", sizeof("_REQUEST") - 1)) |
| 91 | ) | 141 | ) |
| 92 | ) { | 142 | ) { |
| 93 | if (!silent) { | 143 | if (!silent) { |
| @@ -96,14 +146,14 @@ static inline int php_varname_check(char *name, int name_len, zend_bool silent T | |||
| 96 | return FAILURE; | 146 | return FAILURE; |
| 97 | } else if (name[0] == 'H' && | 147 | } else if (name[0] == 'H' && |
| 98 | ( | 148 | ( |
| 99 | (name_len == sizeof("HTTP_POST_VARS") && !memcmp(name, "HTTP_POST_VARS", sizeof("HTTP_POST_VARS"))) || | 149 | (name_len == sizeof("HTTP_POST_VARS") - 1 && !memcmp(name, "HTTP_POST_VARS", sizeof("HTTP_POST_VARS") - 1)) || |
| 100 | (name_len == sizeof("HTTP_GET_VARS") && !memcmp(name, "HTTP_GET_VARS", sizeof("HTTP_GET_VARS"))) || | 150 | (name_len == sizeof("HTTP_GET_VARS") - 1 && !memcmp(name, "HTTP_GET_VARS", sizeof("HTTP_GET_VARS") - 1)) || |
| 101 | (name_len == sizeof("HTTP_COOKIE_VARS") && !memcmp(name, "HTTP_COOKIE_VARS", sizeof("HTTP_COOKIE_VARS"))) || | 151 | (name_len == sizeof("HTTP_COOKIE_VARS") - 1 && !memcmp(name, "HTTP_COOKIE_VARS", sizeof("HTTP_COOKIE_VARS") - 1)) || |
| 102 | (name_len == sizeof("HTTP_ENV_VARS") && !memcmp(name, "HTTP_ENV_VARS", sizeof("HTTP_ENV_VARS"))) || | 152 | (name_len == sizeof("HTTP_ENV_VARS") - 1 && !memcmp(name, "HTTP_ENV_VARS", sizeof("HTTP_ENV_VARS") - 1)) || |
| 103 | (name_len == sizeof("HTTP_SERVER_VARS") && !memcmp(name, "HTTP_SERVER_VARS", sizeof("HTTP_SERVER_VARS"))) || | 153 | (name_len == sizeof("HTTP_SERVER_VARS") - 1 && !memcmp(name, "HTTP_SERVER_VARS", sizeof("HTTP_SERVER_VARS") - 1)) || |
| 104 | (name_len == sizeof("HTTP_SESSION_VARS") && !memcmp(name, "HTTP_SESSION_VARS", sizeof("HTTP_SESSION_VARS"))) || | 154 | (name_len == sizeof("HTTP_SESSION_VARS") - 1 && !memcmp(name, "HTTP_SESSION_VARS", sizeof("HTTP_SESSION_VARS") - 1)) || |
| 105 | (name_len == sizeof("HTTP_RAW_POST_DATA") && !memcmp(name, "HTTP_RAW_POST_DATA", sizeof("HTTP_RAW_POST_DATA"))) || | 155 | (name_len == sizeof("HTTP_RAW_POST_DATA") - 1 && !memcmp(name, "HTTP_RAW_POST_DATA", sizeof("HTTP_RAW_POST_DATA") - 1)) || |
| 106 | (name_len == sizeof("HTTP_POST_FILES") && !memcmp(name, "HTTP_POST_FILES", sizeof("HTTP_POST_FILES"))) | 156 | (name_len == sizeof("HTTP_POST_FILES") - 1 && !memcmp(name, "HTTP_POST_FILES", sizeof("HTTP_POST_FILES") - 1)) |
| 107 | ) | 157 | ) |
| 108 | ) { | 158 | ) { |
| 109 | if (!silent) { | 159 | if (!silent) { |
| @@ -113,7 +163,6 @@ static inline int php_varname_check(char *name, int name_len, zend_bool silent T | |||
| 113 | } | 163 | } |
| 114 | return SUCCESS; | 164 | return SUCCESS; |
| 115 | } | 165 | } |
| 116 | /* }}} */ | ||
| 117 | #endif | 166 | #endif |
| 118 | 167 | ||
| 119 | ZEND_BEGIN_MODULE_GLOBALS(suhosin) | 168 | ZEND_BEGIN_MODULE_GLOBALS(suhosin) |
| @@ -133,7 +133,7 @@ static int check_fileupload_varname(char *varname) | |||
| 133 | 133 | ||
| 134 | /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */ | 134 | /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */ |
| 135 | /* This is to protect several silly scripts that do globalizing themself */ | 135 | /* This is to protect several silly scripts that do globalizing themself */ |
| 136 | if (php_varname_check(var, var_len, 1 TSRMLS_CC) == FAILURE) { | 136 | if (php_varname_check(var, var_len, 1 TSRMLS_CC) == FAILURE || suhosin_is_protected_varname(var, var_len)) { |
| 137 | suhosin_log(S_FILES, "tried to register forbidden variable '%s' through FILE variables", var); | 137 | suhosin_log(S_FILES, "tried to register forbidden variable '%s' through FILE variables", var); |
| 138 | if (!SUHOSIN_G(simulation)) { | 138 | if (!SUHOSIN_G(simulation)) { |
| 139 | goto return_failure; | 139 | goto return_failure; |
