|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
[2015-10-05 07:20 UTC] stas@php.net
-Status: Open
+Status: Feedback
[2015-10-05 07:20 UTC] stas@php.net
[2015-10-05 08:12 UTC] taoguangchen at icloud dot com
-Status: Feedback
+Status: Open
[2015-10-05 08:12 UTC] taoguangchen at icloud dot com
[2015-10-05 08:14 UTC] stas@php.net
-Type: Security
+Type: Feature/Change Request
[2016-03-17 07:49 UTC] taoguangchen at icloud dot com
-Status: Open
+Status: Closed
[2016-03-17 07:49 UTC] taoguangchen at icloud dot com
|
|||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Mon Nov 03 09:00:02 2025 UTC |
Description: ------------ three years ago i had reported this bug, and until today some applications still make this mistake again. var_unserializer.re: ``` "s:" uiv ":" ["] { ... if (*(YYCURSOR) != '"') { *p = YYCURSOR; return 0; } YYCURSOR += 2; *p = YYCURSOR; INIT_PZVAL(*rval); ZVAL_STRINGL(*rval, str, len, 1); return 1; } "S:" uiv ":" ["] { ... if (*(YYCURSOR) != '"') { efree(str); *p = YYCURSOR; return 0; } YYCURSOR += 2; *p = YYCURSOR; INIT_PZVAL(*rval); ZVAL_STRINGL(*rval, str, len, 0); return 1; } ``` so this should be a invalid deserialized string can be deserialized into a valid string-type ZVAL. ex: ``` unserialize('s:4:"ryat"x'); ``` security risks: some applications still use unserialize() handle user input data, and use blacklist check way to fix security issue. the latest security patch of SMF (similar fix way has also been used IPB): ``` function safe_unserialize($serialized) { // Must be a string and not contain null bytes. if (is_string($serialized) && strpos( $serialized, "\0" ) === false) { // unserialize will only accept objects declared with O rather than o and is strict on whitespace. // If not found, or we found something that smelled odd but wasn't actually an object, we're good. if (strpos($serialized, 'O:') === false || !preg_match('~(^|;|{|})O:[+\-0-9]+:"~', $serialized)) return @unserialize($serialized); } return false; } ``` so an attacker can bypass this fix easily: ``` safe_unserialize('a:1:{s:4:"ryat"xO:8:"stdClass":0:{}}'); ``` fix: ``` + if (*(YYCURSOR+1) != ';') { + *p = YYCURSOR+1; + return 0; + } YYCURSOR += 2; *p = YYCURSOR; ```