laminas / laminas-http

Provides an easy interface for performing Hyper-Text Transfer Protocol (HTTP) requests
https://docs.laminas.dev/laminas-http/
BSD 3-Clause "New" or "Revised" License
36 stars 27 forks source link

Security tightening: verify a stream file name is a string before unlinking #48

Closed weierophinney closed 3 years ago

weierophinney commented 3 years ago

Per CVE-2021-3007 (and as reported on Bleeping Computer there is a possibility IF A USER HAS USED UNSERIALIZE() ON UNTRUSTED DATA of the stream response destructor potentially invoking a class __toString() implementation, and thus triggering a vulnerability.

This patch ensures that given that scenario, the stream response destructor does not use an object as a string for purposes of unlinking a potential stream filename.


Additional information

The Laminas security team was contacted on 2020-11-27 about a potential vulnerability in the MVC skeleton. After analysis, we responded on 2020-11-30 with the following:

On review, we feel this is not a vulnerability specific to the framework, but rather
more generally to the language. The un/serialize() functions have a long history
of vulnerabilities (please see https://www.google.com/search?q=php+unserialize+RCE
for examples), and developers should NEVER use it on untrusted input. If this is
impossible, they should at the very least pass the second `$options` argument,
and provide a list of allowed classes, or use the argument to disallow all
unserialization of objects (see https://www.php.net/unserialize for details).

We also received the report you provided against Zend Framework. That project
is no longer active, and any security issues are now resolved in the Laminas
Project (which will require users migrate to Laminas from ZF). Our findings remain
the same for that project, however; this is a PHP language issue, and not specific
to our project.

The Open Web Application Security Project (OWASP) has a classification for this sort of vulnerability: PHP Object Injection. It is not specific to any given framework, and presents itself when an application blindly unserializes user input that includes classes with __destruct() methods and/or methods that might get called within the application context (including other magic methods such as __toString()). The same vulnerability could have been achieved even easier by providing a serialized class with a __destruct() method defined, as the method would be called as soon as the object was out of scope.

Regardless, we are providing this patch to help further protect our users from these scenarios. The patch provides type checking of the $streamName property before performing a cleanup operation (which results in an unlink() operation, which, previously, could have resulted in an implied call to an an object's __toString() method) in the Laminas\Http\Response\Stream destructor.