diff options
| -rw-r--r-- | ex_imp.c | 59 | ||||
| -rw-r--r-- | ifilter.c | 54 | ||||
| -rw-r--r-- | php_suhosin.h | 50 | ||||
| -rw-r--r-- | ufilter.c | 52 |
4 files changed, 59 insertions, 156 deletions
| @@ -443,6 +443,7 @@ PHP_FUNCTION(suhosin_extract) | |||
| 443 | /* }}} */ | 443 | /* }}} */ |
| 444 | 444 | ||
| 445 | 445 | ||
| 446 | |||
| 446 | #if PHP_VERSION_ID >= 50300 | 447 | #if PHP_VERSION_ID >= 50300 |
| 447 | static int copy_request_variable(void *pDest TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) | 448 | static int copy_request_variable(void *pDest TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) |
| 448 | { | 449 | { |
| @@ -478,35 +479,6 @@ static int copy_request_variable(void *pDest TSRMLS_DC, int num_args, va_list ar | |||
| 478 | return 0; | 479 | return 0; |
| 479 | } | 480 | } |
| 480 | 481 | ||
| 481 | if (Z_STRVAL(new_key)[0] == 'H') { | ||
| 482 | if ((strcmp(Z_STRVAL(new_key), "HTTP_GET_VARS")==0)|| | ||
| 483 | (strcmp(Z_STRVAL(new_key), "HTTP_POST_VARS")==0)|| | ||
| 484 | (strcmp(Z_STRVAL(new_key), "HTTP_POST_FILES")==0)|| | ||
| 485 | (strcmp(Z_STRVAL(new_key), "HTTP_ENV_VARS")==0)|| | ||
| 486 | (strcmp(Z_STRVAL(new_key), "HTTP_SERVER_VARS")==0)|| | ||
| 487 | (strcmp(Z_STRVAL(new_key), "HTTP_SESSION_VARS")==0)|| | ||
| 488 | (strcmp(Z_STRVAL(new_key), "HTTP_COOKIE_VARS")==0)|| | ||
| 489 | (strcmp(Z_STRVAL(new_key), "HTTP_RAW_POST_DATA")==0)) { | ||
| 490 | zval_dtor(&new_key); | ||
| 491 | return 0; | ||
| 492 | } | ||
| 493 | } else if (Z_STRVAL(new_key)[0] == '_') { | ||
| 494 | if ((strcmp(Z_STRVAL(new_key), "_COOKIE")==0)|| | ||
| 495 | (strcmp(Z_STRVAL(new_key), "_ENV")==0)|| | ||
| 496 | (strcmp(Z_STRVAL(new_key), "_FILES")==0)|| | ||
| 497 | (strcmp(Z_STRVAL(new_key), "_GET")==0)|| | ||
| 498 | (strcmp(Z_STRVAL(new_key), "_POST")==0)|| | ||
| 499 | (strcmp(Z_STRVAL(new_key), "_REQUEST")==0)|| | ||
| 500 | (strcmp(Z_STRVAL(new_key), "_SESSION")==0)|| | ||
| 501 | (strcmp(Z_STRVAL(new_key), "_SERVER")==0)) { | ||
| 502 | zval_dtor(&new_key); | ||
| 503 | return 0; | ||
| 504 | } | ||
| 505 | } else if (strcmp(Z_STRVAL(new_key), "GLOBALS")==0) { | ||
| 506 | zval_dtor(&new_key); | ||
| 507 | return 0; | ||
| 508 | } | ||
| 509 | |||
| 510 | zend_delete_global_variable(Z_STRVAL(new_key), Z_STRLEN(new_key) TSRMLS_CC); | 482 | zend_delete_global_variable(Z_STRVAL(new_key), Z_STRLEN(new_key) TSRMLS_CC); |
| 511 | ZEND_SET_SYMBOL_WITH_LENGTH(&EG(symbol_table), Z_STRVAL(new_key), Z_STRLEN(new_key) + 1, *var, Z_REFCOUNT_PP(var) + 1, 0); | 483 | ZEND_SET_SYMBOL_WITH_LENGTH(&EG(symbol_table), Z_STRVAL(new_key), Z_STRLEN(new_key) + 1, *var, Z_REFCOUNT_PP(var) + 1, 0); |
| 512 | 484 | ||
| @@ -554,35 +526,6 @@ static int copy_request_variable(void *pDest, int num_args, va_list args, zend_h | |||
| 554 | return 0; | 526 | return 0; |
| 555 | } | 527 | } |
| 556 | 528 | ||
| 557 | if (new_key[0] == 'H') { | ||
| 558 | if ((strcmp(new_key, "HTTP_GET_VARS")==0)|| | ||
| 559 | (strcmp(new_key, "HTTP_POST_VARS")==0)|| | ||
| 560 | (strcmp(new_key, "HTTP_POST_FILES")==0)|| | ||
| 561 | (strcmp(new_key, "HTTP_ENV_VARS")==0)|| | ||
| 562 | (strcmp(new_key, "HTTP_SERVER_VARS")==0)|| | ||
| 563 | (strcmp(new_key, "HTTP_SESSION_VARS")==0)|| | ||
| 564 | (strcmp(new_key, "HTTP_COOKIE_VARS")==0)|| | ||
| 565 | (strcmp(new_key, "HTTP_RAW_POST_DATA")==0)) { | ||
| 566 | efree(new_key); | ||
| 567 | return 0; | ||
| 568 | } | ||
| 569 | } else if (new_key[0] == '_') { | ||
| 570 | if ((strcmp(new_key, "_COOKIE")==0)|| | ||
| 571 | (strcmp(new_key, "_ENV")==0)|| | ||
| 572 | (strcmp(new_key, "_FILES")==0)|| | ||
| 573 | (strcmp(new_key, "_GET")==0)|| | ||
| 574 | (strcmp(new_key, "_POST")==0)|| | ||
| 575 | (strcmp(new_key, "_REQUEST")==0)|| | ||
| 576 | (strcmp(new_key, "_SESSION")==0)|| | ||
| 577 | (strcmp(new_key, "_SERVER")==0)) { | ||
| 578 | efree(new_key); | ||
| 579 | return 0; | ||
| 580 | } | ||
| 581 | } else if (strcmp(new_key, "GLOBALS")==0) { | ||
| 582 | efree(new_key); | ||
| 583 | return 0; | ||
| 584 | } | ||
| 585 | |||
| 586 | #if PHP_MAJOR_VERSION > 5 || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 0) | 529 | #if PHP_MAJOR_VERSION > 5 || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 0) |
| 587 | zend_delete_global_variable(new_key, new_key_len-1 TSRMLS_CC); | 530 | zend_delete_global_variable(new_key, new_key_len-1 TSRMLS_CC); |
| 588 | #else | 531 | #else |
| @@ -29,6 +29,7 @@ | |||
| 29 | #include "ext/standard/info.h" | 29 | #include "ext/standard/info.h" |
| 30 | #include "php_suhosin.h" | 30 | #include "php_suhosin.h" |
| 31 | #include "php_variables.h" | 31 | #include "php_variables.h" |
| 32 | #include "ext/standard/php_var.h" | ||
| 32 | 33 | ||
| 33 | 34 | ||
| 34 | static void (*orig_register_server_variables)(zval *track_vars_array TSRMLS_DC) = NULL; | 35 | static void (*orig_register_server_variables)(zval *track_vars_array TSRMLS_DC) = NULL; |
| @@ -619,47 +620,11 @@ unsigned int suhosin_input_filter(int arg, char *var, char **val, unsigned int v | |||
| 619 | 620 | ||
| 620 | /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */ | 621 | /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */ |
| 621 | /* This is to protect several silly scripts that do globalizing themself */ | 622 | /* This is to protect several silly scripts that do globalizing themself */ |
| 622 | 623 | if (php_varname_check(var, var_len, 0 TSRMLS_CC) == FAILURE) { | |
| 623 | switch (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 | case 18: | 625 | if (!SUHOSIN_G(simulation)) { |
| 625 | if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname; | 626 | return 0; |
| 626 | break; | 627 | } |
| 627 | case 17: | ||
| 628 | if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname; | ||
| 629 | break; | ||
| 630 | case 16: | ||
| 631 | if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname; | ||
| 632 | if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname; | ||
| 633 | break; | ||
| 634 | case 15: | ||
| 635 | if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname; | ||
| 636 | break; | ||
| 637 | case 14: | ||
| 638 | if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname; | ||
| 639 | break; | ||
| 640 | case 13: | ||
| 641 | if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname; | ||
| 642 | if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname; | ||
| 643 | break; | ||
| 644 | case 8: | ||
| 645 | if (memcmp(var, "_SESSION", 8)==0) goto protected_varname; | ||
| 646 | if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname; | ||
| 647 | break; | ||
| 648 | case 7: | ||
| 649 | if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname; | ||
| 650 | if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname; | ||
| 651 | if (memcmp(var, "_SERVER", 7)==0) goto protected_varname; | ||
| 652 | break; | ||
| 653 | case 6: | ||
| 654 | if (memcmp(var, "_FILES", 6)==0) goto protected_varname; | ||
| 655 | break; | ||
| 656 | case 5: | ||
| 657 | if (memcmp(var, "_POST", 5)==0) goto protected_varname; | ||
| 658 | break; | ||
| 659 | case 4: | ||
| 660 | if (memcmp(var, "_ENV", 4)==0) goto protected_varname; | ||
| 661 | if (memcmp(var, "_GET", 4)==0) goto protected_varname; | ||
| 662 | break; | ||
| 663 | } | 628 | } |
| 664 | 629 | ||
| 665 | /* Okay let PHP register this variable */ | 630 | /* Okay let PHP register this variable */ |
| @@ -681,13 +646,6 @@ unsigned int suhosin_input_filter(int arg, char *var, char **val, unsigned int v | |||
| 681 | } | 646 | } |
| 682 | 647 | ||
| 683 | return 1; | 648 | return 1; |
| 684 | protected_varname: | ||
| 685 | suhosin_log(S_VARS, "tried to register forbidden variable '%s' through %s variables", var, arg == PARSE_GET ? "GET" : arg == PARSE_POST ? "POST" : "COOKIE"); | ||
| 686 | if (!SUHOSIN_G(simulation)) { | ||
| 687 | return 0; | ||
| 688 | } else { | ||
| 689 | return 1; | ||
| 690 | } | ||
| 691 | } | 649 | } |
| 692 | /* }}} */ | 650 | /* }}} */ |
| 693 | 651 | ||
diff --git a/php_suhosin.h b/php_suhosin.h index 22e6df1..e89d02b 100644 --- a/php_suhosin.h +++ b/php_suhosin.h | |||
| @@ -39,6 +39,10 @@ | |||
| 39 | #endif | 39 | #endif |
| 40 | #endif | 40 | #endif |
| 41 | 41 | ||
| 42 | #ifndef PHP_VERSION_ID | ||
| 43 | #define PHP_VERSION_ID (PHP_MAJOR_VERSION * 10000 + PHP_MINOR_VERSION * 100 + PHP_RELEASE_VERSION) | ||
| 44 | #endif | ||
| 45 | |||
| 42 | extern zend_module_entry suhosin_module_entry; | 46 | extern zend_module_entry suhosin_module_entry; |
| 43 | #define phpext_suhosin_ptr &suhosin_module_entry | 47 | #define phpext_suhosin_ptr &suhosin_module_entry |
| 44 | 48 | ||
| @@ -66,6 +70,52 @@ PHP_MINFO_FUNCTION(suhosin); | |||
| 66 | 70 | ||
| 67 | #include "ext/standard/basic_functions.h" | 71 | #include "ext/standard/basic_functions.h" |
| 68 | 72 | ||
| 73 | #if PHP_VERSION_ID < 50203 | ||
| 74 | static inline int php_varname_check(char *name, int name_len, zend_bool silent TSRMLS_DC) /* {{{ */ | ||
| 75 | { | ||
| 76 | if (name_len == sizeof("GLOBALS") && !memcmp(name, "GLOBALS", sizeof("GLOBALS"))) { | ||
| 77 | if (!silent) { | ||
| 78 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attempted GLOBALS variable overwrite"); | ||
| 79 | } | ||
| 80 | return FAILURE; | ||
| 81 | } else if (name[0] == '_' && | ||
| 82 | ( | ||
| 83 | (name_len == sizeof("_GET") && !memcmp(name, "_GET", sizeof("_GET"))) || | ||
| 84 | (name_len == sizeof("_POST") && !memcmp(name, "_POST", sizeof("_POST"))) || | ||
| 85 | (name_len == sizeof("_COOKIE") && !memcmp(name, "_COOKIE", sizeof("_COOKIE"))) || | ||
| 86 | (name_len == sizeof("_ENV") && !memcmp(name, "_ENV", sizeof("_ENV"))) || | ||
| 87 | (name_len == sizeof("_SERVER") && !memcmp(name, "_SERVER", sizeof("_SERVER"))) || | ||
| 88 | (name_len == sizeof("_SESSION") && !memcmp(name, "_SESSION", sizeof("_SESSION"))) || | ||
| 89 | (name_len == sizeof("_FILES") && !memcmp(name, "_FILES", sizeof("_FILES"))) || | ||
| 90 | (name_len == sizeof("_REQUEST") && !memcmp(name, "_REQUEST", sizeof("_REQUEST"))) | ||
| 91 | ) | ||
| 92 | ) { | ||
| 93 | if (!silent) { | ||
| 94 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attempted super-global (%s) variable overwrite", name); | ||
| 95 | } | ||
| 96 | return FAILURE; | ||
| 97 | } else if (name[0] == 'H' && | ||
| 98 | ( | ||
| 99 | (name_len == sizeof("HTTP_POST_VARS") && !memcmp(name, "HTTP_POST_VARS", sizeof("HTTP_POST_VARS"))) || | ||
| 100 | (name_len == sizeof("HTTP_GET_VARS") && !memcmp(name, "HTTP_GET_VARS", sizeof("HTTP_GET_VARS"))) || | ||
| 101 | (name_len == sizeof("HTTP_COOKIE_VARS") && !memcmp(name, "HTTP_COOKIE_VARS", sizeof("HTTP_COOKIE_VARS"))) || | ||
| 102 | (name_len == sizeof("HTTP_ENV_VARS") && !memcmp(name, "HTTP_ENV_VARS", sizeof("HTTP_ENV_VARS"))) || | ||
| 103 | (name_len == sizeof("HTTP_SERVER_VARS") && !memcmp(name, "HTTP_SERVER_VARS", sizeof("HTTP_SERVER_VARS"))) || | ||
| 104 | (name_len == sizeof("HTTP_SESSION_VARS") && !memcmp(name, "HTTP_SESSION_VARS", sizeof("HTTP_SESSION_VARS"))) || | ||
| 105 | (name_len == sizeof("HTTP_RAW_POST_DATA") && !memcmp(name, "HTTP_RAW_POST_DATA", sizeof("HTTP_RAW_POST_DATA"))) || | ||
| 106 | (name_len == sizeof("HTTP_POST_FILES") && !memcmp(name, "HTTP_POST_FILES", sizeof("HTTP_POST_FILES"))) | ||
| 107 | ) | ||
| 108 | ) { | ||
| 109 | if (!silent) { | ||
| 110 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attempted long input array (%s) overwrite", name); | ||
| 111 | } | ||
| 112 | return FAILURE; | ||
| 113 | } | ||
| 114 | return SUCCESS; | ||
| 115 | } | ||
| 116 | /* }}} */ | ||
| 117 | #endif | ||
| 118 | |||
| 69 | ZEND_BEGIN_MODULE_GLOBALS(suhosin) | 119 | ZEND_BEGIN_MODULE_GLOBALS(suhosin) |
| 70 | zend_uint in_code_type; | 120 | zend_uint in_code_type; |
| 71 | long execution_depth; | 121 | long execution_depth; |
| @@ -30,60 +30,13 @@ | |||
| 30 | #include "php_suhosin.h" | 30 | #include "php_suhosin.h" |
| 31 | #include "php_variables.h" | 31 | #include "php_variables.h" |
| 32 | #include "suhosin_rfc1867.h" | 32 | #include "suhosin_rfc1867.h" |
| 33 | #include "ext/standard/php_var.h" | ||
| 33 | 34 | ||
| 34 | PHP_SUHOSIN_API int (*old_rfc1867_callback)(unsigned int event, void *event_data, void **extra TSRMLS_DC) = NULL; | 35 | PHP_SUHOSIN_API int (*old_rfc1867_callback)(unsigned int event, void *event_data, void **extra TSRMLS_DC) = NULL; |
| 35 | #if !HAVE_RFC1867_CALLBACK | 36 | #if !HAVE_RFC1867_CALLBACK |
| 36 | PHP_SUHOSIN_API int (*php_rfc1867_callback)(unsigned int event, void *event_data, void **extra TSRMLS_DC) = NULL; | 37 | PHP_SUHOSIN_API int (*php_rfc1867_callback)(unsigned int event, void *event_data, void **extra TSRMLS_DC) = NULL; |
| 37 | #endif | 38 | #endif |
| 38 | 39 | ||
| 39 | static int is_protected_varname(char *var, int var_len) | ||
| 40 | { | ||
| 41 | switch (var_len) { | ||
| 42 | case 18: | ||
| 43 | if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname2; | ||
| 44 | break; | ||
| 45 | case 17: | ||
| 46 | if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname2; | ||
| 47 | break; | ||
| 48 | case 16: | ||
| 49 | if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname2; | ||
| 50 | if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname2; | ||
| 51 | break; | ||
| 52 | case 15: | ||
| 53 | if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname2; | ||
| 54 | break; | ||
| 55 | case 14: | ||
| 56 | if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname2; | ||
| 57 | break; | ||
| 58 | case 13: | ||
| 59 | if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname2; | ||
| 60 | if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname2; | ||
| 61 | break; | ||
| 62 | case 8: | ||
| 63 | if (memcmp(var, "_SESSION", 8)==0) goto protected_varname2; | ||
| 64 | if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname2; | ||
| 65 | break; | ||
| 66 | case 7: | ||
| 67 | if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname2; | ||
| 68 | if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname2; | ||
| 69 | if (memcmp(var, "_SERVER", 7)==0) goto protected_varname2; | ||
| 70 | break; | ||
| 71 | case 6: | ||
| 72 | if (memcmp(var, "_FILES", 6)==0) goto protected_varname2; | ||
| 73 | break; | ||
| 74 | case 5: | ||
| 75 | if (memcmp(var, "_POST", 5)==0) goto protected_varname2; | ||
| 76 | break; | ||
| 77 | case 4: | ||
| 78 | if (memcmp(var, "_ENV", 4)==0) goto protected_varname2; | ||
| 79 | if (memcmp(var, "_GET", 4)==0) goto protected_varname2; | ||
| 80 | break; | ||
| 81 | } | ||
| 82 | |||
| 83 | return 0; | ||
| 84 | protected_varname2: | ||
| 85 | return 1; | ||
| 86 | } | ||
| 87 | 40 | ||
| 88 | /* {{{ SAPI_UPLOAD_VARNAME_FILTER_FUNC | 41 | /* {{{ SAPI_UPLOAD_VARNAME_FILTER_FUNC |
| 89 | */ | 42 | */ |
| @@ -180,8 +133,7 @@ static int check_fileupload_varname(char *varname) | |||
| 180 | 133 | ||
| 181 | /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */ | 134 | /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */ |
| 182 | /* This is to protect several silly scripts that do globalizing themself */ | 135 | /* This is to protect several silly scripts that do globalizing themself */ |
| 183 | 136 | if (php_varname_check(var, var_len, 0 TSRMLS_CC) == FAILURE) { | |
| 184 | if (is_protected_varname(var, var_len)) { | ||
| 185 | 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); |
| 186 | if (!SUHOSIN_G(simulation)) { | 138 | if (!SUHOSIN_G(simulation)) { |
| 187 | goto return_failure; | 139 | goto return_failure; |
