]> granicus.if.org Git - php/commitdiff
Added max_input_vars directive to prevent attacks based on hash collisions
authorDmitry Stogov <dmitry@php.net>
Thu, 15 Dec 2011 08:47:03 +0000 (08:47 +0000)
committerDmitry Stogov <dmitry@php.net>
Thu, 15 Dec 2011 08:47:03 +0000 (08:47 +0000)
NEWS
main/main.c
main/php_globals.h
main/php_variables.c

diff --git a/NEWS b/NEWS
index 52f1200867e038b9e381a712e70f309506c6b333..ac14281145331dc28c4e26a0c0b0d81ff49195b2 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,10 @@ PHP                                                                        NEWS
 |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 ?? ??? 2011, PHP 5.3.9
 
+- Core:
+  . Added max_input_vars directive to prevent attacks based on hash collisions
+    (Dmitry).
+
 - Streams:
   . Fixed bug #60455 (stream_get_line misbehaves if EOF is not detected together
     with the last read). (Gustavo)
index 8e52412cdd2618c3d98a9f1a7b0eaafb66b897da..c512f2652dc67a0a294a4f6a2a0a9b437c184ecd 100644 (file)
@@ -512,6 +512,7 @@ PHP_INI_BEGIN()
        STD_PHP_INI_ENTRY("post_max_size",                      "8M",           PHP_INI_SYSTEM|PHP_INI_PERDIR,          OnUpdateLong,                   post_max_size,                  sapi_globals_struct,sapi_globals)
        STD_PHP_INI_ENTRY("upload_tmp_dir",                     NULL,           PHP_INI_SYSTEM,         OnUpdateStringUnempty,  upload_tmp_dir,                 php_core_globals,       core_globals)
        STD_PHP_INI_ENTRY("max_input_nesting_level", "64",              PHP_INI_SYSTEM|PHP_INI_PERDIR,          OnUpdateLongGEZero,     max_input_nesting_level,                        php_core_globals,       core_globals)
+       STD_PHP_INI_ENTRY("max_input_vars",                     "1000",         PHP_INI_SYSTEM|PHP_INI_PERDIR,          OnUpdateLongGEZero,     max_input_vars,                                         php_core_globals,       core_globals)
 
        STD_PHP_INI_ENTRY("user_dir",                           NULL,           PHP_INI_SYSTEM,         OnUpdateString,                 user_dir,                               php_core_globals,       core_globals)
        STD_PHP_INI_ENTRY("variables_order",            "EGPCS",        PHP_INI_SYSTEM|PHP_INI_PERDIR,          OnUpdateStringUnempty,  variables_order,                php_core_globals,       core_globals)
index f4316fb675de5223ebf1db4f638af5af81215efe..d0be82c0e92110543a80fd90887d13aa12a64e33 100644 (file)
@@ -174,6 +174,8 @@ struct _php_core_globals {
 #ifdef PHP_WIN32
        zend_bool windows_show_crt_warning;
 #endif
+
+       long max_input_vars;
 };
 
 
index 73803e136d2daa007a857b9a07e0ddf35a5870bb..40d549a93712859d7af45829fc8b8ba01519103c 100644 (file)
@@ -191,6 +191,9 @@ PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars
                                }
                                if (zend_symtable_find(symtable1, escaped_index, index_len + 1, (void **) &gpc_element_p) == FAILURE
                                        || Z_TYPE_PP(gpc_element_p) != IS_ARRAY) {
+                                       if (zend_hash_num_elements(symtable1) >= PG(max_input_vars)) {
+                                               php_error_docref(NULL TSRMLS_CC, E_ERROR, "Input variables exceeded %ld. To increase the limit change max_input_vars in php.ini.", PG(max_input_vars));
+                                       }
                                        MAKE_STD_ZVAL(gpc_element);
                                        array_init(gpc_element);
                                        zend_symtable_update(symtable1, escaped_index, index_len + 1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p);
@@ -236,6 +239,9 @@ plain_var:
                                zend_symtable_exists(symtable1, escaped_index, index_len + 1)) {
                                zval_ptr_dtor(&gpc_element);
                        } else {
+                               if (zend_hash_num_elements(symtable1) >= PG(max_input_vars)) {
+                                       php_error_docref(NULL TSRMLS_CC, E_ERROR, "Input variables exceeded %ld. To increase the limit change max_input_vars in php.ini.", PG(max_input_vars));
+                               }
                                zend_symtable_update(symtable1, escaped_index, index_len + 1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p);
                        }
                        if (escaped_index != index) {