rasmus Wed Feb 19 14:41:10 2003 EDT Added files: /php4 README.input_filter
Modified files: /php4/ext/mbstring mb_gpc.c mbstring.c /php4/main SAPI.c SAPI.h php_content_types.c php_variables.c rfc1867.c Log: Input Filter support. See README.input_filter for details. @- Input Filter support added. See README.input_filter. (Rasmus)
Index: php4/ext/mbstring/mb_gpc.c diff -u php4/ext/mbstring/mb_gpc.c:1.3 php4/ext/mbstring/mb_gpc.c:1.4 --- php4/ext/mbstring/mb_gpc.c:1.3 Tue Dec 31 11:06:52 2002 +++ php4/ext/mbstring/mb_gpc.c Wed Feb 19 14:41:07 2003 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: mb_gpc.c,v 1.3 2002/12/31 16:06:52 sebastian Exp $ */ +/* $Id: mb_gpc.c,v 1.4 2003/02/19 19:41:07 rasmus Exp $ */ /* {{{ includes */ #ifdef HAVE_CONFIG_H @@ -169,7 +169,7 @@ break; } - _php_mb_encoding_handler_ex(array_ptr, res, separator, 0, 0 TSRMLS_CC); + _php_mb_encoding_handler_ex(arg, array_ptr, res, separator, 0, 0 TSRMLS_CC); if (MBSTRG(http_input_identify) != mbfl_no_encoding_invalid) { switch(arg){ @@ -199,7 +199,7 @@ /* }}} */ /* {{{ int _php_mb_encoding_handler_ex() */ -int _php_mb_encoding_handler_ex(zval *arg, char *res, char *separator, int force_register_globals, int report_errors TSRMLS_DC) +int _php_mb_encoding_handler_ex(int data_type, zval *arg, char *res, char *separator, +int force_register_globals, int report_errors TSRMLS_DC) { char *var, *val, *s1, *s2; char *strtok_buf = NULL, **val_list = NULL; @@ -342,6 +342,7 @@ val_len = len_list[n]; } n++; + val_len = sapi_module.input_filter(data_type, var, val, val_len +TSRMLS_CC); /* add variable to symbol table */ php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC); if (convd != NULL){ Index: php4/ext/mbstring/mbstring.c diff -u php4/ext/mbstring/mbstring.c:1.163 php4/ext/mbstring/mbstring.c:1.164 --- php4/ext/mbstring/mbstring.c:1.163 Tue Feb 18 15:31:04 2003 +++ php4/ext/mbstring/mbstring.c Wed Feb 19 14:41:07 2003 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: mbstring.c,v 1.163 2003/02/18 20:31:04 moriyoshi Exp $ */ +/* $Id: mbstring.c,v 1.164 2003/02/19 19:41:07 rasmus Exp $ */ /* * PHP4 Multibyte String module "mbstring" @@ -1281,7 +1281,7 @@ encstr = estrndup(encstr, encstr_len); - RETVAL_BOOL(_php_mb_encoding_handler_ex(track_vars_array, encstr, separator, (track_vars_array == NULL), 1 TSRMLS_CC)); + RETVAL_BOOL(_php_mb_encoding_handler_ex(PARSE_STRING, track_vars_array, +encstr, separator, (track_vars_array == NULL), 1 TSRMLS_CC)); if (encstr != NULL) efree(encstr); if (separator != NULL) efree(separator); Index: php4/main/SAPI.c diff -u php4/main/SAPI.c:1.171 php4/main/SAPI.c:1.172 --- php4/main/SAPI.c:1.171 Tue Feb 11 16:44:02 2003 +++ php4/main/SAPI.c Wed Feb 19 14:41:07 2003 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: SAPI.c,v 1.171 2003/02/11 21:44:02 sesser Exp $ */ +/* $Id: SAPI.c,v 1.172 2003/02/19 19:41:07 rasmus Exp $ */ #include <ctype.h> #include <sys/stat.h> @@ -823,6 +823,11 @@ return SUCCESS; } +SAPI_API int sapi_register_input_filter(unsigned int (*input_filter)(int arg, char +*var, char *val, unsigned int val_len TSRMLS_DC)) +{ + sapi_module.input_filter = input_filter; + return SUCCESS; +} SAPI_API int sapi_flush(TSRMLS_D) { Index: php4/main/SAPI.h diff -u php4/main/SAPI.h:1.98 php4/main/SAPI.h:1.99 --- php4/main/SAPI.h:1.98 Wed Feb 19 03:40:17 2003 +++ php4/main/SAPI.h Wed Feb 19 14:41:07 2003 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: SAPI.h,v 1.98 2003/02/19 08:40:17 sniper Exp $ */ +/* $Id: SAPI.h,v 1.99 2003/02/19 19:41:07 rasmus Exp $ */ #ifndef SAPI_H #define SAPI_H @@ -178,6 +178,7 @@ SAPI_API void sapi_unregister_post_entry(sapi_post_entry *post_entry); SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(TSRMLS_D)); SAPI_API int sapi_register_treat_data(void (*treat_data)(int arg, char *str, zval *destArray TSRMLS_DC)); +SAPI_API int sapi_register_input_filter(unsigned int (*input_filter)(int arg, char +*var, char *val, unsigned int val_len TSRMLS_DC)); SAPI_API int sapi_flush(TSRMLS_D); SAPI_API struct stat *sapi_get_stat(TSRMLS_D); @@ -238,6 +239,8 @@ int (*get_target_uid)(uid_t * TSRMLS_DC); int (*get_target_gid)(gid_t * TSRMLS_DC); + + unsigned int (*input_filter)(int arg, char *var, char *val, unsigned int +val_len TSRMLS_DC); }; @@ -266,10 +269,12 @@ #define SAPI_POST_HANDLER_FUNC(post_handler) void post_handler(char *content_type_dup, void *arg TSRMLS_DC) #define SAPI_TREAT_DATA_FUNC(treat_data) void treat_data(int arg, char *str, zval* destArray TSRMLS_DC) +#define SAPI_INPUT_FILTER_FUNC(input_filter) unsigned int input_filter(int arg, char +*var, char *val, unsigned int val_len TSRMLS_DC) SAPI_API SAPI_POST_READER_FUNC(sapi_read_standard_form_data); SAPI_API SAPI_POST_READER_FUNC(php_default_post_reader); SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data); +SAPI_API SAPI_INPUT_FILTER_FUNC(php_default_input_filter); #define STANDARD_SAPI_MODULE_PROPERTIES Index: php4/main/php_content_types.c diff -u php4/main/php_content_types.c:1.26 php4/main/php_content_types.c:1.27 --- php4/main/php_content_types.c:1.26 Tue Dec 31 10:58:53 2002 +++ php4/main/php_content_types.c Wed Feb 19 14:41:08 2003 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_content_types.c,v 1.26 2002/12/31 15:58:53 sebastian Exp $ */ +/* $Id: php_content_types.c,v 1.27 2003/02/19 19:41:08 rasmus Exp $ */ #include "php.h" #include "SAPI.h" @@ -77,6 +77,7 @@ sapi_register_post_entries(php_post_entries); sapi_register_default_post_reader(php_default_post_reader); sapi_register_treat_data(php_default_treat_data); + sapi_register_input_filter(php_default_input_filter); return SUCCESS; } /* }}} */ Index: php4/main/php_variables.c diff -u php4/main/php_variables.c:1.49 php4/main/php_variables.c:1.50 --- php4/main/php_variables.c:1.49 Wed Feb 19 03:40:19 2003 +++ php4/main/php_variables.c Wed Feb 19 14:41:08 2003 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_variables.c,v 1.49 2003/02/19 08:40:19 sniper Exp $ */ +/* $Id: php_variables.c,v 1.50 2003/02/19 19:41:08 rasmus Exp $ */ #include <stdio.h> #include "php.h" @@ -226,12 +226,19 @@ *val++ = '\0'; php_url_decode(var, strlen(var)); val_len = php_url_decode(val, strlen(val)); + val_len = sapi_module.input_filter(PARSE_POST, var, val, +val_len TSRMLS_CC); php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC); } var = php_strtok_r(NULL, "&", &strtok_buf); } } +SAPI_API SAPI_INPUT_FILTER_FUNC(php_default_input_filter) +{ + /* TODO: check .ini setting here and apply user-defined input filter */ + return val_len; +} + SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data) { char *res = NULL, *var, *val, *separator=NULL; @@ -314,6 +321,7 @@ *val++ = '\0'; php_url_decode(var, strlen(var)); val_len = php_url_decode(val, strlen(val)); + val_len = sapi_module.input_filter(arg, var, val, val_len +TSRMLS_CC); php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC); } else { php_url_decode(var, strlen(var)); Index: php4/main/rfc1867.c diff -u php4/main/rfc1867.c:1.132 php4/main/rfc1867.c:1.133 --- php4/main/rfc1867.c:1.132 Wed Feb 19 03:40:19 2003 +++ php4/main/rfc1867.c Wed Feb 19 14:41:09 2003 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: rfc1867.c,v 1.132 2003/02/19 08:40:19 sniper Exp $ */ +/* $Id: rfc1867.c,v 1.133 2003/02/19 19:41:09 rasmus Exp $ */ /* * This product includes software developed by the Apache Group @@ -805,6 +805,7 @@ value = estrdup(""); } + sapi_module.input_filter(PARSE_POST, param, value, +strlen(value) TSRMLS_CC); safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC); if (!strcmp(param, "MAX_FILE_SIZE")) { max_file_size = atol(value); Index: php4/README.input_filter +++ php4/README.input_filter Input Filter Support in PHP5 ---------------------------- XSS (Cross Site Scripting) hacks are becoming more and more prevalent, and can be quite difficult to prevent. Whenever you accept user data and somehow display this data back to users, you are likely vulnerable to XSS hacks. The Input Filter support in PHP5 is aimed at providing the framework through which a company-wide or site-wide security policy can be enforced. It is implemented as a SAPI hook and is called from the treat_data and post handler functions. To implement your own security policy you will need to write a standard PHP extension. A simple implementation might look like the following. This stores the original raw user data and adds a my_get_raw() function while the normal $_POST, $_GET and $_COOKIE arrays are only populated with stripped data. In this simple example all I am doing is calling strip_tags() on the data. If register_globals is turned on, the default globals that are created will be stripped ($foo) while a $RAW_foo is created with the original user input. ZEND_BEGIN_MODULE_GLOBALS(my_input_filter) zval *post_array; zval *get_array; zval *cookie_array; ZEND_END_MODULE_GLOBALS(my_input_filter) #ifdef ZTS #define IF_G(v) TSRMG(my_input_filter_globals_id, zend_my_input_filter_globals *, v) #else #define IF_G(v) (my_input_filter_globals.v) #endif ZEND_DECLARE_MODULE_GLOBALS(my_input_filter) function_entry my_input_filter_functions[] = { PHP_FE(my_get_raw, NULL) {NULL, NULL, NULL} }; zend_module_entry my_input_filter_module_entry = { STANDARD_MODULE_HEADER, "my_input_filter", my_input_filter_functions, PHP_MINIT(my_input_filter), PHP_MSHUTDOWN(my_input_filter), NULL, PHP_RSHUTDOWN(my_input_filter), PHP_MINFO(my_input_filter), "0.1", STANDARD_MODULE_PROPERTIES }; PHP_MINIT_FUNCTION(my_input_filter) { ZEND_INIT_MODULE_GLOBALS(my_input_filter, php_my_input_filter_init_globals, NULL); REGISTER_LONG_CONSTANT("POST", PARSE_POST, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("GET", PARSE_GET, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("COOKIE", PARSE_COOKIE, CONST_CS | CONST_PERSISTENT); sapi_register_input_filter(my_sapi_input_filter); return SUCCESS; } PHP_RSHUTDOWN_FUNCTION(my_input_filter) { if(IF_G(get_array)) { zval_ptr_dtor(&IF_G(get_array)); IF_G(get_array) = NULL; } if(IF_G(post_array)) { zval_ptr_dtor(&IF_G(post_array)); IF_G(post_array) = NULL; } if(IF_G(cookie_array)) { zval_ptr_dtor(&IF_G(cookie_array)); IF_G(cookie_array) = NULL; } return SUCCESS; } PHP_MINFO_FUNCTION(my_input_filter) { php_info_print_table_start(); php_info_print_table_row( 2, "My Input Filter Support", "enabled" ); php_info_print_table_row( 2, "Revision", "$Revision: 1.1 $"); php_info_print_table_end(); } unsigned int my_sapi_input_filter(int arg, char *var, char *val, unsigned int val_len) { zval new_var; zval *array_ptr = NULL; char *raw_var; int var_len; assert(val != NULL); switch(arg) { case PARSE_GET: if(!IF_G(get_array)) { ALLOC_ZVAL(array_ptr); array_init(array_ptr); INIT_PZVAL(array_ptr); } IF_G(get_array) = array_ptr; break; case PARSE_POST: if(!IF_G(post_array)) { ALLOC_ZVAL(array_ptr); array_init(array_ptr); INIT_PZVAL(array_ptr); } IF_G(post_array) = array_ptr; break; case PARSE_COOKIE: if(!IF_G(cookie_array)) { ALLOC_ZVAL(array_ptr); array_init(array_ptr); INIT_PZVAL(array_ptr); } IF_G(cookie_array) = array_ptr; break; } Z_STRLEN(new_var) = val_len; Z_STRVAL(new_var) = estrndup(val, val_len); Z_TYPE(new_var) = IS_STRING; var_len = strlen(var); raw_var = emalloc(var_len+5); /* RAW_ and a \0 */ strcpy(raw_var, "RAW_"); strlcat(raw_var,var,var_len+5); php_register_variable_ex(raw_var, &new_var, array_ptr TSRMLS_DC); php_strip_tags(val, val_len, NULL, NULL, 0); return strlen(val); } PHP_FUNCTION(my_get_raw) { long arg; char *var; int var_len; zval **tmp; zval *array_ptr = NULL; HashTable *hash_ptr; char *raw_var; if(zend_parse_parameters(2 TSRMLS_CC, "ls|l", &arg, &var, &var_len) == FAILURE) { return; } switch(arg) { case PARSE_GET: array_ptr = IF_G(get_array); break; case PARSE_POST: array_ptr = IF_G(post_array); break; case PARSE_COOKIE: array_ptr = IF_G(post_array); break; } if(!array_ptr) RETURN_FALSE; /* * I'm changing the variable name here because when running with register_globals on, * the variable will end up in the global symbol table */ raw_var = emalloc(var_len+5); /* RAW_ and a \0 */ strcpy(raw_var, "RAW_"); strlcat(raw_var,var,var_len+5); hash_ptr = HASH_OF(array_ptr); if(zend_hash_find(hash_ptr, raw_var, var_len+5, (void **)&tmp) == SUCCESS) { *return_value = **tmp; zval_copy_ctor(return_value); } else { RETVAL_FALSE; } efree(raw_var); }
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php