diff options
author | Zeev Suraski <zeev@php.net> | 2000-09-09 15:02:15 +0000 |
---|---|---|
committer | Zeev Suraski <zeev@php.net> | 2000-09-09 15:02:15 +0000 |
commit | b7ecaacd07b6be07677ed694b5dbc51b609c4263 (patch) | |
tree | 56a4ab13d9b42bc669a63c61314f3b67f794ee20 | |
parent | 242139d5acb8ff26a42e8f41eb15558458ca8e58 (diff) | |
download | php-git-b7ecaacd07b6be07677ed694b5dbc51b609c4263.tar.gz |
More security-related (control) patches:
- Avoid displaying errors during startup, unless display_startup_errors is enabled.
- Implemented post_size_max limit. Defaults to 8MB.
- Implemented file_uploads on/off directive (defaults to on).
-rw-r--r-- | main/SAPI.c | 25 | ||||
-rw-r--r-- | main/SAPI.h | 3 | ||||
-rw-r--r-- | main/main.c | 22 | ||||
-rw-r--r-- | main/php_globals.h | 7 | ||||
-rw-r--r-- | main/php_ini.c | 26 | ||||
-rw-r--r-- | main/php_ini.h | 1 | ||||
-rw-r--r-- | main/rfc1867.c | 11 | ||||
-rw-r--r-- | php.ini-dist | 17 | ||||
-rw-r--r-- | php.ini-optimized | 17 | ||||
-rw-r--r-- | php.ini-recommended | 17 |
10 files changed, 120 insertions, 26 deletions
diff --git a/main/SAPI.c b/main/SAPI.c index 7853292383..df1d5fb957 100644 --- a/main/SAPI.c +++ b/main/SAPI.c @@ -115,8 +115,10 @@ SAPI_API void sapi_handle_post(void *arg SLS_DC) { if (SG(request_info).post_entry) { SG(request_info).post_entry->post_handler(SG(request_info).content_type_dup, arg SLS_CC); - efree(SG(request_info).post_data); - SG(request_info).post_data = NULL; + if (SG(request_info).post_data) { + efree(SG(request_info).post_data); + SG(request_info).post_data = NULL; + } efree(SG(request_info).content_type_dup); SG(request_info).content_type_dup = NULL; } @@ -156,7 +158,7 @@ static void sapi_read_post_data(SLS_D) post_reader_func = post_entry->post_reader; } else { if (!sapi_module.default_post_reader) { - sapi_module.sapi_error(E_ERROR, "Unsupported content type: '%s'", content_type); + sapi_module.sapi_error(E_WARNING, "Unsupported content type: '%s'", content_type); return; } SG(request_info).post_entry = NULL; @@ -175,6 +177,11 @@ SAPI_POST_READER_FUNC(sapi_read_standard_form_data) int read_bytes; int allocated_bytes=SAPI_POST_BLOCK_SIZE+1; + if (SG(request_info).content_length > SG(post_max_size)) { + php_error(E_WARNING, "POST Content-Length of %d bytes exceeds the limit of %d bytes", + SG(request_info).content_length, SG(post_max_size)); + return; + } SG(request_info).post_data = emalloc(allocated_bytes); for (;;) { @@ -183,6 +190,10 @@ SAPI_POST_READER_FUNC(sapi_read_standard_form_data) break; } SG(read_post_bytes) += read_bytes; + if (SG(read_post_bytes) > SG(post_max_size)) { + php_error(E_WARNING, "Actual POST length does not match Content-Length, and exceeds %d bytes", SG(post_max_size)); + return; + } if (read_bytes < SAPI_POST_BLOCK_SIZE) { break; } @@ -285,14 +296,17 @@ SAPI_API void sapi_activate(SLS_D) } else { SG(request_info).headers_only = 0; } + SG(rfc1867_uploaded_files) = NULL; if (SG(server_context)) { if (SG(request_info).request_method && !strcmp(SG(request_info).request_method, "POST")) { if (!SG(request_info).content_type) { - sapi_module.sapi_error(E_ERROR, "No content-type in POST request"); + sapi_module.sapi_error(E_WARNING, "No content-type in POST request"); + SG(request_info).content_type_dup = NULL; + } else { + sapi_read_post_data(SLS_C); } - sapi_read_post_data(SLS_C); } else { SG(request_info).content_type_dup = NULL; } @@ -301,7 +315,6 @@ SAPI_API void sapi_activate(SLS_D) sapi_module.activate(SLS_C); } } - SG(rfc1867_uploaded_files) = NULL; } diff --git a/main/SAPI.h b/main/SAPI.h index d1cef23f7b..da2894e742 100644 --- a/main/SAPI.h +++ b/main/SAPI.h @@ -64,7 +64,7 @@ typedef struct { char *query_string; char *post_data; char *cookie_data; - uint content_length; + long content_length; uint post_data_length; char *path_translated; @@ -101,6 +101,7 @@ typedef struct { char *default_mimetype; char *default_charset; HashTable *rfc1867_uploaded_files; + long post_max_size; } sapi_globals_struct; diff --git a/main/main.c b/main/main.c index a87cf5969b..9601c0abd0 100644 --- a/main/main.c +++ b/main/main.c @@ -122,7 +122,7 @@ static PHP_INI_MH(OnChangeMemoryLimit) int new_limit; if (new_value) { - new_limit = atoi(new_value); + new_limit = php_atoi(new_value); } else { new_limit = 1<<30; /* effectively, no limit */ } @@ -207,6 +207,7 @@ PHP_INI_BEGIN() STD_PHP_INI_BOOLEAN("allow_call_time_pass_reference","1",PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateBool, allow_call_time_pass_reference, zend_compiler_globals, compiler_globals) STD_PHP_INI_BOOLEAN("asp_tags", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateBool, asp_tags, zend_compiler_globals, compiler_globals) STD_PHP_INI_BOOLEAN("display_errors", "1", PHP_INI_ALL, OnUpdateBool, display_errors, php_core_globals, core_globals) + STD_PHP_INI_BOOLEAN("display_startup_errors", "0", PHP_INI_ALL, OnUpdateBool, display_startup_errors, php_core_globals, core_globals) STD_PHP_INI_BOOLEAN("enable_dl", "1", PHP_INI_SYSTEM, OnUpdateBool, enable_dl, php_core_globals, core_globals) STD_PHP_INI_BOOLEAN("error_append_string", NULL, PHP_INI_ALL, OnUpdateString, error_append_string, php_core_globals, core_globals) STD_PHP_INI_BOOLEAN("error_prepend_string", NULL, PHP_INI_ALL, OnUpdateString, error_prepend_string, php_core_globals, core_globals) @@ -240,7 +241,9 @@ PHP_INI_BEGIN() PHP_INI_ENTRY("max_execution_time", "30", PHP_INI_ALL, OnUpdateTimeout) STD_PHP_INI_ENTRY("open_basedir", NULL, PHP_INI_SYSTEM, OnUpdateStringUnempty, open_basedir, php_core_globals, core_globals) STD_PHP_INI_ENTRY("safe_mode_exec_dir", "1", PHP_INI_SYSTEM, OnUpdateString, safe_mode_exec_dir, php_core_globals, core_globals) - STD_PHP_INI_ENTRY("upload_max_filesize", "2097152", PHP_INI_ALL, OnUpdateInt, upload_max_filesize, php_core_globals, core_globals) + STD_PHP_INI_ENTRY("upload_max_filesize", "2M", PHP_INI_ALL, OnUpdateInt, upload_max_filesize, php_core_globals, core_globals) + STD_PHP_INI_ENTRY("file_uploads", "1", PHP_INI_ALL, OnUpdateBool, file_uploads, php_core_globals, core_globals) + STD_PHP_INI_ENTRY("post_max_size", "8M", PHP_INI_SYSTEM, OnUpdateInt, 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("user_dir", NULL, PHP_INI_SYSTEM, OnUpdateStringUnempty, user_dir, php_core_globals, core_globals) STD_PHP_INI_ENTRY("variables_order", NULL, PHP_INI_ALL, OnUpdateStringUnempty, variables_order, php_core_globals, core_globals) @@ -249,7 +252,7 @@ PHP_INI_BEGIN() PHP_INI_ENTRY("browscap", NULL, PHP_INI_SYSTEM, NULL) PHP_INI_ENTRY("error_reporting", NULL, PHP_INI_ALL, OnUpdateErrorReporting) #if MEMORY_LIMIT - PHP_INI_ENTRY("memory_limit", "8388608", PHP_INI_ALL, OnChangeMemoryLimit) + PHP_INI_ENTRY("memory_limit", "8M", PHP_INI_ALL, OnChangeMemoryLimit) #endif PHP_INI_ENTRY("precision", "14", PHP_INI_ALL, OnSetPrecision) PHP_INI_ENTRY("sendmail_from", NULL, PHP_INI_ALL, NULL) @@ -384,7 +387,8 @@ static void php_error_cb(int type, const char *error_filename, const uint error_ snprintf(log_buffer, 1024, "PHP %s: %s in %s on line %d", error_type_str, buffer, error_filename, error_lineno); php_log_err(log_buffer); } - if (module_initialized && PG(display_errors)) { + if (module_initialized && PG(display_errors) + && (!PG(during_request_startup) || PG(display_startup_errors))) { char *prepend_string = INI_STR("error_prepend_string"); char *append_string = INI_STR("error_append_string"); char *error_format; @@ -593,6 +597,8 @@ int php_request_startup(CLS_D ELS_DC PLS_DC SLS_DC) signal(SIGCHLD,sigchld_handler); #endif + PG(during_request_startup) = 1; + global_lock(); php_output_startup(); @@ -616,7 +622,10 @@ int php_request_startup(CLS_D ELS_DC PLS_DC SLS_DC) } else if (PG(implicit_flush)) { php_start_implicit_flush(); } - + + /* We turn this off in php_execute_script() */ + /* PG(during_request_startup) = 0; */ + return SUCCESS; } @@ -825,6 +834,7 @@ int php_module_startup(sapi_module_struct *sf) SG(request_info).headers_only = 0; SG(request_info).argv0 = NULL; PG(connection_status) = PHP_CONNECTION_NORMAL; + PG(during_request_startup) = 0; #if HAVE_SETLOCALE setlocale(LC_CTYPE, ""); @@ -1159,6 +1169,8 @@ PHPAPI void php_execute_script(zend_file_handle *primary_file CLS_DC ELS_DC PLS_ UpdateIniFromRegistry(primary_file->filename); #endif + PG(during_request_startup) = 0; + if (primary_file->type == ZEND_HANDLE_FILENAME && primary_file->filename) { V_GETCWD(old_cwd, OLD_CWD_SIZE-1); diff --git a/main/php_globals.h b/main/php_globals.h index 4aec8a6a87..39e9d16200 100644 --- a/main/php_globals.h +++ b/main/php_globals.h @@ -71,6 +71,7 @@ struct _php_core_globals { zend_bool track_errors; zend_bool display_errors; + zend_bool display_startup_errors; zend_bool log_errors; char *error_log; @@ -113,7 +114,11 @@ struct _php_core_globals { zend_bool html_errors; - zend_bool modules_activated; + zend_bool modules_activated; + + zend_bool file_uploads; + + zend_bool during_request_startup; }; diff --git a/main/php_ini.c b/main/php_ini.c index 6f4c870d1f..aec25c3f8c 100644 --- a/main/php_ini.c +++ b/main/php_ini.c @@ -409,6 +409,30 @@ PHPAPI void display_ini_entries(zend_module_entry *module) } +PHPAPI int php_atoi(const char *str, int str_len) +{ + int retval; + + if (!str_len) { + str_len = strlen(str); + } + retval = atoi(str); + if (str_len>0) { + switch (str[str_len-1]) { + case 'k': + case 'K': + retval *= 1024; + break; + case 'm': + case 'M': + retval *= 1048576; + break; + } + } + return retval; +} + + /* Standard message handlers */ PHPAPI PHP_INI_MH(OnUpdateBool) @@ -442,7 +466,7 @@ PHPAPI PHP_INI_MH(OnUpdateInt) p = (long *) (base+(size_t) mh_arg1); - *p = atoi(new_value); + *p = php_atoi(new_value, new_value_length); return SUCCESS; } diff --git a/main/php_ini.h b/main/php_ini.h index 7c5721f6ca..5b1994a711 100644 --- a/main/php_ini.h +++ b/main/php_ini.h @@ -137,6 +137,7 @@ PHPAPI PHP_INI_DISP(display_link_numbers); pval *cfg_get_entry(char *name, uint name_length); +PHPAPI int php_atoi(const char *str, int str_len); /* Standard message handlers */ PHPAPI PHP_INI_MH(OnUpdateBool); diff --git a/main/rfc1867.c b/main/rfc1867.c index 5d5d4fcf6f..d4d4de59c1 100644 --- a/main/rfc1867.c +++ b/main/rfc1867.c @@ -105,7 +105,7 @@ void destroy_uploaded_files_hash(SLS_D) /* * Split raw mime stream up into appropriate components */ -static void php_mime_split(char *buf, int cnt, char *boundary, zval *array_ptr SLS_DC) +static void php_mime_split(char *buf, int cnt, char *boundary, zval *array_ptr SLS_DC PLS_DC) { char *ptr, *loc, *loc2, *loc3, *s, *name, *filename, *u, *temp_filename; int len, state = 0, Done = 0, rem, urem; @@ -119,7 +119,6 @@ static void php_mime_split(char *buf, int cnt, char *boundary, zval *array_ptr S zend_bool upload_successful; zend_bool magic_quotes_gpc; ELS_FETCH(); - PLS_FETCH(); zend_hash_init(&PG(rfc1867_protected_variables), 5, NULL, NULL, 0); @@ -428,6 +427,12 @@ SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) char *boundary; uint boundary_len; zval *array_ptr = (zval *) arg; + PLS_FETCH(); + + if (!PG(file_uploads)) { + php_error(E_WARNING, "File uploads are disabled"); + return; + } boundary = strstr(content_type_dup, "boundary"); if (!boundary || !(boundary=strchr(boundary, '='))) { @@ -438,7 +443,7 @@ SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) boundary_len = strlen(boundary); if (SG(request_info).post_data) { - php_mime_split(SG(request_info).post_data, SG(request_info).post_data_length, boundary, array_ptr SLS_CC); + php_mime_split(SG(request_info).post_data, SG(request_info).post_data_length, boundary, array_ptr SLS_CC PLS_CC); } } diff --git a/php.ini-dist b/php.ini-dist index af572acc85..12096db572 100644 --- a/php.ini-dist +++ b/php.ini-dist @@ -135,7 +135,7 @@ expose_php = On ; Decides whether PHP may expose the fact that it is installed ;;;;;;;;;;;;;;;;;;; max_execution_time = 30 ; Maximum execution time of each script, in seconds -memory_limit = 8388608 ; Maximum amount of memory a script may consume (8MB) +memory_limit = 8M ; Maximum amount of memory a script may consume (8MB) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -167,6 +167,10 @@ display_errors = On ; Print out errors (as a part of the output) ; Keeping display_errors enabled on a production web site may reveal ; security information to end users, such as file paths on your Web server, ; your database schema or other information. +display_startup_errors = Off ; Even when display_errors is on, errors that occur during + ; PHP's startup sequence are not displayed. It's strongly + ; recommended to keep display_startup_errors off, except for + ; when debugging. log_errors = Off ; Log errors into a log file (server-specific log, stderr, or error_log (below)) ; As stated above, you're strongly advised to use error logging in place of ; error displaying on production web sites. @@ -201,6 +205,7 @@ register_argc_argv = On ; This directive tells PHP whether to declare the argv& ; variables (that would contain the GET information). If you ; don't use these variables, you should turn it off for ; increased performance +post_max_size = 8M ; Maximum size of POST data that PHP will accept. gpc_order = "GPC" ; This directive is deprecated. Use variables_order instead. ; Magic quotes @@ -225,8 +230,6 @@ default_mimetype = "text/html" include_path = ; UNIX: "/path1:/path2" Windows: "\path1;\path2" doc_root = ; the root of the php pages, used only if nonempty user_dir = ; the directory under which php opens the script using /~username, used only if nonempty -;upload_tmp_dir = ; temporary directory for HTTP uploaded files (will use system default if not specified) -upload_max_filesize = 2097152 ; 2 Meg default limit on file uploads extension_dir = ./ ; directory in which the loadable extensions (modules) reside enable_dl = On ; Whether or not to enable the dl() function. ; The dl() function does NOT properly work in multithreaded @@ -234,6 +237,14 @@ enable_dl = On ; Whether or not to enable the dl() function. ; on them. +;;;;;;;;;;;;;;;; +; File Uploads ; +;;;;;;;;;;;;;;;; +file_uploads = On ; Whether to allow HTTP file uploads +;upload_tmp_dir = ; temporary directory for HTTP uploaded files (will use system default if not specified) +upload_max_filesize = 2M ; Maximum allowed size for uploaded files + + ;;;;;;;;;;;;;;;;;;;;;; ; Dynamic Extensions ; ;;;;;;;;;;;;;;;;;;;;;; diff --git a/php.ini-optimized b/php.ini-optimized index 901f300dd6..7143b89e27 100644 --- a/php.ini-optimized +++ b/php.ini-optimized @@ -122,7 +122,7 @@ expose_php = On ; Decides whether PHP may expose the fact that it is installed ;;;;;;;;;;;;;;;;;;; max_execution_time = 30 ; Maximum execution time of each script, in seconds -memory_limit = 8388608 ; Maximum amount of memory a script may consume (8MB) +memory_limit = 8M ; Maximum amount of memory a script may consume (8MB) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -154,6 +154,10 @@ display_errors = On ; Print out errors (as a part of the output) ; Keeping display_errors enabled on a production web site may reveal ; security information to end users, such as file paths on your Web server, ; your database schema or other information. +display_startup_errors = Off ; Even when display_errors is on, errors that occur during + ; PHP's startup sequence are not displayed. It's strongly + ; recommended to keep display_startup_errors off, except for + ; when debugging. log_errors = Off ; Log errors into a log file (server-specific log, stderr, or error_log (below)) ; As stated above, you're strongly advised to use error logging in place of ; error displaying on production web sites. @@ -184,6 +188,7 @@ register_argc_argv = Off ; This directive tells PHP whether to declare the argv ; don't use these variables, you should turn it off for ; increased performance (you should try not to use it anyway, ; for less likelihood of security bugs in your code). +post_max_size = 8M ; Maximum size of POST data that PHP will accept. gpc_order = "GPC" ; This directive is deprecated. Use variables_order instead. ; Magic quotes @@ -208,8 +213,6 @@ default_mimetype = "text/html" include_path = ; UNIX: "/path1:/path2" Windows: "\path1;\path2" doc_root = ; the root of the php pages, used only if nonempty user_dir = ; the directory under which php opens the script using /~username, used only if nonempty -;upload_tmp_dir = ; temporary directory for HTTP uploaded files (will use system default if not specified) -upload_max_filesize = 2097152 ; 2 Meg default limit on file uploads extension_dir = ./ ; directory in which the loadable extensions (modules) reside enable_dl = On ; Whether or not to enable the dl() function. ; The dl() function does NOT properly work in multithreaded @@ -217,6 +220,14 @@ enable_dl = On ; Whether or not to enable the dl() function. ; on them. +;;;;;;;;;;;;;;;; +; File Uploads ; +;;;;;;;;;;;;;;;; +file_uploads = On ; Whether to allow HTTP file uploads +;upload_tmp_dir = ; temporary directory for HTTP uploaded files (will use system default if not specified) +upload_max_filesize = 2M ; Maximum allowed size for uploaded files + + ;;;;;;;;;;;;;;;;;;;;;; ; Dynamic Extensions ; ;;;;;;;;;;;;;;;;;;;;;; diff --git a/php.ini-recommended b/php.ini-recommended index 901f300dd6..7143b89e27 100644 --- a/php.ini-recommended +++ b/php.ini-recommended @@ -122,7 +122,7 @@ expose_php = On ; Decides whether PHP may expose the fact that it is installed ;;;;;;;;;;;;;;;;;;; max_execution_time = 30 ; Maximum execution time of each script, in seconds -memory_limit = 8388608 ; Maximum amount of memory a script may consume (8MB) +memory_limit = 8M ; Maximum amount of memory a script may consume (8MB) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -154,6 +154,10 @@ display_errors = On ; Print out errors (as a part of the output) ; Keeping display_errors enabled on a production web site may reveal ; security information to end users, such as file paths on your Web server, ; your database schema or other information. +display_startup_errors = Off ; Even when display_errors is on, errors that occur during + ; PHP's startup sequence are not displayed. It's strongly + ; recommended to keep display_startup_errors off, except for + ; when debugging. log_errors = Off ; Log errors into a log file (server-specific log, stderr, or error_log (below)) ; As stated above, you're strongly advised to use error logging in place of ; error displaying on production web sites. @@ -184,6 +188,7 @@ register_argc_argv = Off ; This directive tells PHP whether to declare the argv ; don't use these variables, you should turn it off for ; increased performance (you should try not to use it anyway, ; for less likelihood of security bugs in your code). +post_max_size = 8M ; Maximum size of POST data that PHP will accept. gpc_order = "GPC" ; This directive is deprecated. Use variables_order instead. ; Magic quotes @@ -208,8 +213,6 @@ default_mimetype = "text/html" include_path = ; UNIX: "/path1:/path2" Windows: "\path1;\path2" doc_root = ; the root of the php pages, used only if nonempty user_dir = ; the directory under which php opens the script using /~username, used only if nonempty -;upload_tmp_dir = ; temporary directory for HTTP uploaded files (will use system default if not specified) -upload_max_filesize = 2097152 ; 2 Meg default limit on file uploads extension_dir = ./ ; directory in which the loadable extensions (modules) reside enable_dl = On ; Whether or not to enable the dl() function. ; The dl() function does NOT properly work in multithreaded @@ -217,6 +220,14 @@ enable_dl = On ; Whether or not to enable the dl() function. ; on them. +;;;;;;;;;;;;;;;; +; File Uploads ; +;;;;;;;;;;;;;;;; +file_uploads = On ; Whether to allow HTTP file uploads +;upload_tmp_dir = ; temporary directory for HTTP uploaded files (will use system default if not specified) +upload_max_filesize = 2M ; Maximum allowed size for uploaded files + + ;;;;;;;;;;;;;;;;;;;;;; ; Dynamic Extensions ; ;;;;;;;;;;;;;;;;;;;;;; |