summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZeev Suraski <zeev@php.net>2000-09-09 15:02:15 +0000
committerZeev Suraski <zeev@php.net>2000-09-09 15:02:15 +0000
commitb7ecaacd07b6be07677ed694b5dbc51b609c4263 (patch)
tree56a4ab13d9b42bc669a63c61314f3b67f794ee20
parent242139d5acb8ff26a42e8f41eb15558458ca8e58 (diff)
downloadphp-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.c25
-rw-r--r--main/SAPI.h3
-rw-r--r--main/main.c22
-rw-r--r--main/php_globals.h7
-rw-r--r--main/php_ini.c26
-rw-r--r--main/php_ini.h1
-rw-r--r--main/rfc1867.c11
-rw-r--r--php.ini-dist17
-rw-r--r--php.ini-optimized17
-rw-r--r--php.ini-recommended17
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 ;
;;;;;;;;;;;;;;;;;;;;;;