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>