Busybox: Upgrade to 1.21.1 (stable). lsof active.
[tomato.git] / release / src / router / php / README.input_filter
blobe2941d029ee4e89f8880c46d41a7e8fc60a7fbc3
1 Input Filter Support in PHP 5
2 -----------------------------
4 XSS (Cross Site Scripting) hacks are becoming more and more prevalent,
5 and can be quite difficult to prevent.  Whenever you accept user data
6 and somehow display this data back to users, you are likely vulnerable
7 to XSS hacks.
9 The Input Filter support in PHP 5 is aimed at providing the framework
10 through which a company-wide or site-wide security policy can be
11 enforced.  It is implemented as a SAPI hook and is called from the
12 treat_data and post handler functions.  To implement your own security
13 policy you will need to write a standard PHP extension.  There is also
14 a powerful standard implementation in ext/filter that should suit most
15 peoples' needs.  However, if you want to implement your own security 
16 policy, read on.
18 A simple implementation might look like the following.  This stores the
19 original raw user data and adds a my_get_raw() function while the normal
20 $_POST, $_GET and $_COOKIE arrays are only populated with stripped
21 data.  In this simple example all I am doing is calling strip_tags() on
22 the data.
24 ZEND_BEGIN_MODULE_GLOBALS(my_input_filter)
25         zval *post_array;
26         zval *get_array;
27         zval *cookie_array;
28 ZEND_END_MODULE_GLOBALS(my_input_filter)
30 #ifdef ZTS
31 #define IF_G(v) TSRMG(my_input_filter_globals_id, zend_my_input_filter_globals *, v)
32 #else
33 #define IF_G(v) (my_input_filter_globals.v)
34 #endif
36 ZEND_DECLARE_MODULE_GLOBALS(my_input_filter)
38 zend_function_entry my_input_filter_functions[] = {
39     PHP_FE(my_get_raw,   NULL)
40     {NULL, NULL, NULL}
43 zend_module_entry my_input_filter_module_entry = {
44     STANDARD_MODULE_HEADER,
45     "my_input_filter",
46     my_input_filter_functions,
47     PHP_MINIT(my_input_filter),
48     PHP_MSHUTDOWN(my_input_filter),
49     NULL,
50     PHP_RSHUTDOWN(my_input_filter),
51     PHP_MINFO(my_input_filter),
52     "0.1",
53     STANDARD_MODULE_PROPERTIES
56 PHP_MINIT_FUNCTION(my_input_filter)
58     ZEND_INIT_MODULE_GLOBALS(my_input_filter, php_my_input_filter_init_globals, NULL);
60     REGISTER_LONG_CONSTANT("POST", PARSE_POST, CONST_CS | CONST_PERSISTENT);
61     REGISTER_LONG_CONSTANT("GET", PARSE_GET, CONST_CS | CONST_PERSISTENT);
62     REGISTER_LONG_CONSTANT("COOKIE", PARSE_COOKIE, CONST_CS | CONST_PERSISTENT);
64     sapi_register_input_filter(my_sapi_input_filter);
65     return SUCCESS;
68 PHP_RSHUTDOWN_FUNCTION(my_input_filter)
70     if(IF_G(get_array)) {
71         zval_ptr_dtor(&IF_G(get_array));
72         IF_G(get_array) = NULL;
73     }
74     if(IF_G(post_array)) {
75         zval_ptr_dtor(&IF_G(post_array));
76         IF_G(post_array) = NULL;
77     }
78     if(IF_G(cookie_array)) {
79         zval_ptr_dtor(&IF_G(cookie_array));
80         IF_G(cookie_array) = NULL;
81     }
82     return SUCCESS;
85 PHP_MINFO_FUNCTION(my_input_filter)
87     php_info_print_table_start();
88     php_info_print_table_row( 2, "My Input Filter Support", "enabled" );
89     php_info_print_table_row( 2, "Revision", "$Id$");
90     php_info_print_table_end();
93 /* The filter handler. If you return 1 from it, then PHP also registers the
94  * (modified) variable. Returning 0 prevents PHP from registering the variable;
95  * you can use this if your filter already registers the variable under a
96  * different name, or if you just don't want the variable registered at all. */
97 SAPI_INPUT_FILTER_FUNC(my_sapi_input_filter)
99     zval new_var;
100     zval *array_ptr = NULL;
101     char *raw_var;
102     int var_len;
104     assert(*val != NULL);
106     switch(arg) {
107         case PARSE_GET:
108             if(!IF_G(get_array)) {
109                 ALLOC_ZVAL(array_ptr);
110                 array_init(array_ptr);
111                 INIT_PZVAL(array_ptr);
112             }
113             IF_G(get_array) = array_ptr;
114             break;
115         case PARSE_POST:
116             if(!IF_G(post_array)) {
117                 ALLOC_ZVAL(array_ptr);
118                 array_init(array_ptr);
119                 INIT_PZVAL(array_ptr);
120             }
121             IF_G(post_array) = array_ptr;
122             break;
123         case PARSE_COOKIE:
124             if(!IF_G(cookie_array)) {
125                 ALLOC_ZVAL(array_ptr);
126                 array_init(array_ptr);
127                 INIT_PZVAL(array_ptr);
128             }
129             IF_G(cookie_array) = array_ptr;
130             break;
131     }
132     Z_STRLEN(new_var) = val_len;
133     Z_STRVAL(new_var) = estrndup(*val, val_len);
134     Z_TYPE(new_var) = IS_STRING;
136     var_len = strlen(var);
137     raw_var = emalloc(var_len+5);  /* RAW_ and a \0 */
138     strcpy(raw_var, "RAW_");
139     strlcat(raw_var,var,var_len+5);
141     php_register_variable_ex(raw_var, &new_var, array_ptr TSRMLS_DC);
143     php_strip_tags(*val, val_len, NULL, NULL, 0);
145     *new_val_len = strlen(*val);
146     return 1;
149 PHP_FUNCTION(my_get_raw)
151     long arg;
152     char *var;
153     int var_len;
154     zval **tmp;
155     zval *array_ptr = NULL;
157     if(zend_parse_parameters(2 TSRMLS_CC, "ls", &arg, &var, &var_len) == FAILURE) {
158         return;
159     }
161     switch(arg) {
162         case PARSE_GET:
163             array_ptr = IF_G(get_array);
164             break;
165         case PARSE_POST:
166             array_ptr = IF_G(post_array);
167             break;
168         case PARSE_COOKIE:
169             array_ptr = IF_G(post_array);
170             break;
171     }
173     if(!array_ptr) {
174         RETURN_FALSE;
175     }
177     if(zend_hash_find(HASH_OF(array_ptr), var, var_len+5, (void **)&tmp) == SUCCESS) {
178         *return_value = **tmp;
179         zval_copy_ctor(return_value);
180     } else {
181         RETVAL_FALSE;
182     }