php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #68088 New Posthandler Potential Illegal efree() vulnerability
Submitted: 2014-09-24 07:06 UTC Modified: 2014-10-06 17:01 UTC
From: tyrael@php.net Assigned: mike (profile)
Status: Closed Package: *General Issues
PHP Version: 5.6.0 OS:
Private report: No CVE-ID: 2014-3622
 [2014-09-24 07:06 UTC] 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


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2014-09-24 07:08 UTC] tyrael@php.net
-CVE-ID: +CVE-ID: 2014-3622
 [2014-09-24 07:08 UTC] tyrael@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: mike
 [2014-09-24 07:08 UTC] 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-10-03 04:26 UTC] rasmus@php.net
-Type: Security +Type: Bug
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 13:01:29 2024 UTC