Annotation of embedaddon/php/README.input_filter, revision 1.1.1.2
1.1 misho 1: Input Filter Support in PHP 5
2: -----------------------------
3:
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.
8:
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.
17:
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
1.1.1.2 ! misho 22: the data.
1.1 misho 23:
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)
29:
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
35:
36: ZEND_DECLARE_MODULE_GLOBALS(my_input_filter)
37:
38: zend_function_entry my_input_filter_functions[] = {
39: PHP_FE(my_get_raw, NULL)
40: {NULL, NULL, NULL}
41: };
42:
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
54: };
55:
56: PHP_MINIT_FUNCTION(my_input_filter)
57: {
58: ZEND_INIT_MODULE_GLOBALS(my_input_filter, php_my_input_filter_init_globals, NULL);
59:
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);
63:
64: sapi_register_input_filter(my_sapi_input_filter);
65: return SUCCESS;
66: }
67:
68: PHP_RSHUTDOWN_FUNCTION(my_input_filter)
69: {
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;
83: }
84:
85: PHP_MINFO_FUNCTION(my_input_filter)
86: {
87: php_info_print_table_start();
88: php_info_print_table_row( 2, "My Input Filter Support", "enabled" );
1.1.1.2 ! misho 89: php_info_print_table_row( 2, "Revision", "$Id: e2941d029ee4e89f8880c46d41a7e8fc60a7fbc3 $");
1.1 misho 90: php_info_print_table_end();
91: }
92:
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)
98: {
99: zval new_var;
100: zval *array_ptr = NULL;
101: char *raw_var;
102: int var_len;
103:
104: assert(*val != NULL);
105:
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;
135:
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);
140:
141: php_register_variable_ex(raw_var, &new_var, array_ptr TSRMLS_DC);
142:
143: php_strip_tags(*val, val_len, NULL, NULL, 0);
144:
145: *new_val_len = strlen(*val);
146: return 1;
147: }
148:
149: PHP_FUNCTION(my_get_raw)
150: {
151: long arg;
152: char *var;
153: int var_len;
154: zval **tmp;
155: zval *array_ptr = NULL;
156:
157: if(zend_parse_parameters(2 TSRMLS_CC, "ls", &arg, &var, &var_len) == FAILURE) {
158: return;
159: }
160:
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: }
172:
1.1.1.2 ! misho 173: if(!array_ptr) {
! 174: RETURN_FALSE;
! 175: }
1.1 misho 176:
1.1.1.2 ! misho 177: if(zend_hash_find(HASH_OF(array_ptr), var, var_len+5, (void **)&tmp) == SUCCESS) {
1.1 misho 178: *return_value = **tmp;
179: zval_copy_ctor(return_value);
180: } else {
181: RETVAL_FALSE;
182: }
183: }
184:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>