php-internal-docs 8.4.8
Unofficial docs for php/php-src
Loading...
Searching...
No Matches
Input filter support in PHP

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 PHP 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. There is also a powerful standard implementation in ext/filter that should suit most peoples' needs. However, if you want to implement your own security policy, read on.

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.

ZEND_BEGIN_MODULE_GLOBALS(my_input_filter)
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_function_entry my_input_filter_functions[] = {
PHP_FE(my_get_raw, NULL)
};
zend_module_entry my_input_filter_module_entry = {
"my_input_filter",
my_input_filter_functions,
PHP_MINIT(my_input_filter),
PHP_MSHUTDOWN(my_input_filter),
PHP_RSHUTDOWN(my_input_filter),
PHP_MINFO(my_input_filter),
"0.1",
};
PHP_MINIT_FUNCTION(my_input_filter)
{
ZEND_INIT_MODULE_GLOBALS(my_input_filter, php_my_input_filter_init_globals, NULL);
sapi_register_input_filter(my_sapi_input_filter);
return SUCCESS;
}
PHP_RSHUTDOWN_FUNCTION(my_input_filter)
{
if(IF_G(get_array)) {
}
}
}
return SUCCESS;
}
PHP_MINFO_FUNCTION(my_input_filter)
{
php_info_print_table_row( 2, "My Input Filter Support", "enabled" );
}
/* The filter handler. If you return 1 from it, then PHP also registers the
* (modified) variable. Returning 0 prevents PHP from registering the variable;
* you can use this if your filter already registers the variable under a
* different name, or if you just don't want the variable registered at all. */
SAPI_INPUT_FILTER_FUNC(my_sapi_input_filter)
{
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;
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);
php_strip_tags(*val, val_len, NULL, NULL, 0);
*new_val_len = strlen(*val);
return 1;
}
PHP_FUNCTION(my_get_raw)
{
long arg;
char *var;
int var_len;
zval **tmp;
zval *array_ptr = NULL;
if(zend_parse_parameters(2, "ls", &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;
array_ptr = IF_G(post_array);
break;
}
if(!array_ptr) {
}
if(zend_hash_find(HASH_OF(array_ptr), var, var_len+5, (void **)&tmp) == SUCCESS) {
*return_value = **tmp;
zval_copy_ctor(return_value);
} else {
}
}
SAPI_API int sapi_register_input_filter(unsigned int(*input_filter)(int arg, const char *var, char **val, size_t val_len, size_t *new_val_len), unsigned int(*input_filter_init)(void))
Definition SAPI.c:991
#define SAPI_INPUT_FILTER_FUNC(input_filter)
Definition SAPI.h:315
assert(mixed $assertion, Throwable|string|null $description=null)
zval * arg
Definition ffi.c:3975
zval * val
Definition ffi.c:4262
#define NULL
Definition gdcache.h:45
#define SUCCESS
Definition hash_sha3.c:261
php_info_print_table_start()
Definition info.c:1064
php_info_print_table_row(2, "PDO Driver for Firebird", "enabled")
php_info_print_table_end()
Definition info.c:1074
#define PHP_FUNCTION
Definition php.h:364
#define PHP_MINFO
Definition php.h:396
#define PHP_MINIT_FUNCTION
Definition php.h:400
#define PHP_MSHUTDOWN
Definition php.h:393
#define strlcat
Definition php.h:169
#define PHP_FE
Definition php.h:369
#define PHP_MINFO_FUNCTION
Definition php.h:404
#define PHP_RSHUTDOWN
Definition php.h:395
#define PHP_RSHUTDOWN_FUNCTION
Definition php.h:403
#define PHP_MINIT
Definition php.h:392
zval get_array
Definition php_filter.h:41
zval cookie_array
Definition php_filter.h:42
#define IF_G(v)
Definition php_filter.h:56
zval post_array
Definition php_filter.h:40
PHPAPI size_t php_strip_tags(char *rbuf, size_t len, const char *allow, size_t allow_len)
Definition string.c:5066
PHPAPI void php_register_variable_ex(const char *var_name, zval *val, zval *track_vars_array)
#define PARSE_COOKIE
#define PARSE_GET
#define PARSE_POST
ZEND_API zend_result zend_parse_parameters(uint32_t num_args, const char *type_spec,...)
Definition zend_API.c:1300
#define RETURN_FALSE
Definition zend_API.h:1058
struct _zend_function_entry zend_function_entry
#define ZEND_INIT_MODULE_GLOBALS(module_name, globals_ctor, globals_dtor)
Definition zend_API.h:272
#define ZEND_DECLARE_MODULE_GLOBALS(module_name)
Definition zend_API.h:268
#define ZEND_END_MODULE_GLOBALS(module_name)
Definition zend_API.h:248
#define HASH_OF(p)
Definition zend_API.h:1062
#define RETVAL_FALSE
Definition zend_API.h:1032
#define ZEND_BEGIN_MODULE_GLOBALS(module_name)
Definition zend_API.h:246
#define array_init(arg)
Definition zend_API.h:537
#define estrndup(s, length)
Definition zend_alloc.h:165
#define emalloc(size)
Definition zend_alloc.h:151
struct _zval_struct zval
strlen(string $string)
#define CONST_PERSISTENT
#define REGISTER_LONG_CONSTANT(name, lval, flags)
ZEND_API zval *ZEND_FASTCALL zend_hash_find(const HashTable *ht, zend_string *key)
Definition zend_hash.c:2668
#define STANDARD_MODULE_HEADER
struct _zend_module_entry zend_module_entry
#define STANDARD_MODULE_PROPERTIES
#define IS_STRING
Definition zend_types.h:606
#define Z_STRVAL(zval)
Definition zend_types.h:974
@ FAILURE
Definition zend_types.h:61
#define Z_STRLEN(zval)
Definition zend_types.h:977
#define Z_TYPE(zval)
Definition zend_types.h:659
ZEND_API void zval_ptr_dtor(zval *zval_ptr)
zval * return_value