File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / README.input_filter
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue May 29 12:34:34 2012 UTC (12 years ago) by misho
Branches: php, MAIN
CVS tags: v5_4_3elwix, v5_4_29p0, v5_4_29, v5_4_20p0, v5_4_20, v5_4_17p0, v5_4_17, HEAD
php 5.4.3+patches

    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
   22: the data.
   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" );
   89:     php_info_print_table_row( 2, "Revision", "$Id: README.input_filter,v 1.1.1.2 2012/05/29 12:34:34 misho Exp $");
   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: 
  173:     if(!array_ptr) {
  174:         RETURN_FALSE;
  175:     }
  176: 
  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:     }
  183: }
  184: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>