Sec Bug->Bug #68088 [Csd]: New Posthandler Potential Illegal efree() vulnerability

From: Date: Fri, 03 Oct 2014 04:26:11 +0000
Subject: Sec Bug->Bug #68088 [Csd]: New Posthandler Potential Illegal efree() vulnerability
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-187813@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=68088&edit=1 ID: 68088 Updated by: rasmus@php.net Reported by: tyrael@php.net Summary: New Posthandler Potential Illegal efree() vulnerability Status: Closed -Type: Security +Type: Bug Package: *General Issues PHP Version: 5.6.0 Assigned To: mike Block user comment: N Private report: Y CVE-ID: 2014-3622 Previous Comments: ------------------------------------------------------------------------ [2014-09-24 07:08:36] tyrael@php.net The fix for this bug has been committed. Snapshots of the sources are packaged every three hours; this change will be in the next snapshot. You can grab the snapshot at http://snaps.php.net/. For Windows: http://windows.php.net/snapshots/ Thank you for the report, and for helping us make PHP better. ------------------------------------------------------------------------ [2014-09-24 07:06:22] tyrael@php.net Description: ------------ Reported by Stefan Esser: today I got a bug report for Suhosin about a Problem with PHP 5.6 support in the Post Handler. Basically a post like var1=&var2=blub resulted in var1 not being registered and Suhosin ALERTing of a NUL byte attack. I therefore looked at the code that I copied from PHP 5.6 and realized that the new Post Handler is doing something dangerous. add_post_var() has the following code in it: ksep = memchr(var->ptr, '=', vsep - var->ptr); if (ksep) { *ksep = '\0'; /* "foo=bar&" or "foo=&" */ klen = ksep - var->ptr; vlen = vsep - ++ksep; } else { ksep = ""; /* "foo&" */ klen = vsep - var->ptr; vlen = 0; } php_url_decode(var->ptr, klen); if (vlen) { vlen = php_url_decode(ksep, vlen); } if (sapi_module.input_filter(PARSE_POST, var->ptr, &ksep, vlen, &new_vlen TSRMLS_CC)) { php_register_variable_safe(var->ptr, ksep, new_vlen, arr TSRMLS_CC); } var->ptr = vsep + (vsep != var->end); return 1; The problem here is that input filters are allowed to change the value. This is why the value is given to it as a char **. As you can see from the code above it gives &ksep to the input filter. This is potentially unsafe. And this is why all other places that invoke the input_filter do a estrndup() before they call the input filter. Right now this is not an exploitable problem, because in order for this to be a big problem the called input filter must do something like freeing the value supplied. Then we would have an illegal efree() that is potentially exploitable for remote code execution. However currently I am not aware of anything using input filters except for ext/filter and suhosin. Both are not doing anything to the value. But if there is some 3rd party possibly binary only filter extension out there that modifies value it might result in a remotely exploitable problem for PHP 5.6+. BTW: you can see in Suhosin how you should fix it. https://github.com/stefanesser/suhosin/commit/36fbfd148ec65a5bfe91fcd666f3b693b06f1699 ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=68088&edit=1

« previous php.bugs (#187813) next »