iliaa           Tue Dec 26 17:23:33 2006 UTC

  Modified files:              (Branch: PHP_4_4)
    /php-src/ext/session        session.c 
  Log:
  MFH: Session deserializer protection.
  
  
http://cvs.php.net/viewvc.cgi/php-src/ext/session/session.c?r1=1.336.2.53.2.9&r2=1.336.2.53.2.10&diff_format=u
Index: php-src/ext/session/session.c
diff -u php-src/ext/session/session.c:1.336.2.53.2.9 
php-src/ext/session/session.c:1.336.2.53.2.10
--- php-src/ext/session/session.c:1.336.2.53.2.9        Wed Dec 20 19:31:40 2006
+++ php-src/ext/session/session.c       Tue Dec 26 17:23:33 2006
@@ -17,7 +17,7 @@
    +----------------------------------------------------------------------+
  */
 
-/* $Id: session.c,v 1.336.2.53.2.9 2006/12/20 19:31:40 tony2001 Exp $ */
+/* $Id: session.c,v 1.336.2.53.2.10 2006/12/26 17:23:33 iliaa Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -418,33 +418,33 @@
        int namelen;
        int has_value;
        php_unserialize_data_t var_hash;
-       int globals_on = PG(register_globals);
 
        PHP_VAR_UNSERIALIZE_INIT(var_hash);
 
        for (p = val; p < endptr; ) {
+               zval **tmp;
                namelen = *p & (~PS_BIN_UNDEF);
                has_value = *p & PS_BIN_UNDEF ? 0 : 1;
 
                name = estrndup(p + 1, namelen);
                
                p += namelen + 1;
-               if (globals_on && namelen == sizeof("_SESSION")-1 && 
!memcmp(name, "_SESSION", sizeof("_SESSION") - 1)) {
-                       /* _SESSION hijack attempt */
-               } else if (globals_on && namelen == sizeof("GLOBALS")-1 && 
!memcmp(name, "GLOBALS", sizeof("GLOBALS") - 1)) {
-                       /* _GLOBALS hijack attempt */
-               } else if (globals_on && namelen == 
sizeof("HTTP_SESSION_VARS")-1 && !memcmp(name, "HTTP_SESSION_VARS", 
sizeof("HTTP_SESSION_VARS")-1)) {
-                       /* HTTP_SESSION_VARS hijack attempt */
-               } else {
-                       if (has_value) {
-                               ALLOC_INIT_ZVAL(current);
-                               if (php_var_unserialize(&current, (const 
unsigned char **)&p, endptr, &var_hash TSRMLS_CC)) {
-                                       php_set_session_var(name, namelen, 
current, &var_hash  TSRMLS_CC);
-                               }
-                               zval_ptr_dtor(&current);
+
+               if (zend_hash_find(&EG(symbol_table), name, namelen + 1, (void 
**) &tmp) == SUCCESS) {
+                       if ((Z_TYPE_PP(tmp) == IS_ARRAY && Z_ARRVAL_PP(tmp) == 
&EG(symbol_table)) || *tmp == PS(http_session_vars)) {
+                               efree(name);
+                               continue;
+                       }
+               }
+
+               if (has_value) {
+                       ALLOC_INIT_ZVAL(current);
+                       if (php_var_unserialize(&current, (const unsigned char 
**)&p, endptr, &var_hash TSRMLS_CC)) {
+                               php_set_session_var(name, namelen, current, 
&var_hash  TSRMLS_CC);
                        }
-                       PS_ADD_VARL(name, namelen);
+                       zval_ptr_dtor(&current);
                }
+               PS_ADD_VARL(name, namelen);
                efree(name);
        }
 
@@ -496,13 +496,13 @@
        int namelen;
        int has_value;
        php_unserialize_data_t var_hash;
-       int globals_on = PG(register_globals);
 
        PHP_VAR_UNSERIALIZE_INIT(var_hash);
 
        p = val;
 
        while (p < endptr) {
+               zval **tmp;
                q = p;
                while (*q != PS_DELIMITER)
                        if (++q >= endptr) goto break_outer_loop;
@@ -517,23 +517,23 @@
                namelen = q - p;
                name = estrndup(p, namelen);
                q++;
-               
-               if (globals_on && namelen == sizeof("_SESSION")-1 && 
!memcmp(name, "_SESSION", sizeof("_SESSION") - 1)) {
-                       /* _SESSION hijack attempt */
-               } else if (globals_on && namelen == sizeof("GLOBALS")-1 && 
!memcmp(name, "GLOBALS", sizeof("GLOBALS") - 1)) {
-                       /* _GLOBALS hijack attempt */
-               } else if (globals_on && namelen == 
sizeof("HTTP_SESSION_VARS")-1 && !memcmp(name, "HTTP_SESSION_VARS", 
sizeof("HTTP_SESSION_VARS")-1)) {
-                       /* HTTP_SESSION_VARS hijack attempt */
-               } else { 
-                       if (has_value) {
-                               ALLOC_INIT_ZVAL(current);
-                               if (php_var_unserialize(&current, (const 
unsigned char **)&q, endptr, &var_hash TSRMLS_CC)) {
-                                       php_set_session_var(name, namelen, 
current, &var_hash TSRMLS_CC);
-                               }
-                               zval_ptr_dtor(&current);
+
+               if (zend_hash_find(&EG(symbol_table), name, namelen + 1, (void 
**) &tmp) == SUCCESS) {
+                       if ((Z_TYPE_PP(tmp) == IS_ARRAY && Z_ARRVAL_PP(tmp) == 
&EG(symbol_table)) || *tmp == PS(http_session_vars)) {
+                               efree(name);
+                               goto skip;
+                       }
+               }
+
+               if (has_value) {
+                       ALLOC_INIT_ZVAL(current);
+                       if (php_var_unserialize(&current, (const unsigned char 
**)&q, endptr, &var_hash TSRMLS_CC)) {
+                               php_set_session_var(name, namelen, current, 
&var_hash TSRMLS_CC);
                        }
-                       PS_ADD_VARL(name, namelen);
+                       zval_ptr_dtor(&current);
                }
+               PS_ADD_VARL(name, namelen);
+skip:
                efree(name);
                
                p = q;

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to