Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [day] [month] [year] [list]
Date: Sat, 05 Nov 2016 03:30:41 -0500
Subject: CVE Request: PHP with Zend OPCache  code permission/sensitive data
 protection vulnerabilities


I did not discover this, but to my knowledge no CVE has been requested 
to date.
The PHP project was informed of this vulnerability over 2 years ago and 
has not
fixed it. I am hoping more public discussion with a CVE will help to 


Affects PHP with Zend OPCache enabled, PHP5 <= 5.6.27 and PHP7 <= 7.0.12

Zend OPCache has code permission and sensitive data protection 
when deployed on shared hosting web servers.


OPCache uses shared memory to cache compiled PHP "opcode" between HTTP 
for reuse. A single shared memory object is opened and initialized in a 
process, and child processes inherit its file descriptor. Due to this 
OPCache is intended for use with a SAPI with a peristent parent process, 
example php-fpm with its master process, or apache2handler where 
occurs in the Apache parent process.

Cache keys for compiled scripts have two modes of operation, simple
filenames and a "use_cwd" mode which includes additional information 
such as
parent script and working directory in cache keys. The "use_cwd" 
behavior only
occurs when scripts are invoked via relative paths, rare in practice in 
a web
server environment with common web applications. In most circumstances 
cache uses a simple filesystem path as a cache key for a cached script's
compiled form.

On shared servers PHP is often deployed so that it will switch to a 
local user
account before running a script, for example using mod_ruid2 if deployed 
as an
Apache module, or using "pools" if deployed as php-fpm. In these
configurations, users expect that they can protect sensitive information 
in PHP
scripts with filesystem permissions.


The single shared OPCache circumvents filesystem permissions. For 
example, when
user alice's WordPress site is requested, PHP runs as user alice and
wp-config.php is read, compiled, and cached, including constants for 
credentials, API auth keys, and hash salts.  User bob can then include 
wp-config.php script via the persistent OPCache, regardless of the 
script's file permissions. User bob only has to know the filesystem path 
of the

PHP's open_basedir setting is also circumvented; with a restrictive
open_basedir, a nonfatal error occurs, but a cached script outside of
open_basedir will still load and run.

If PHP is running in chroots, unintentional cross-user script execution 
occur due to filename hash key collisions. This might be considered a 
bug, but both stem from the simplistic design of opcache keys.

With a default configuration (other than the zend_extension directive to 
OPCache, which is not loaded by default) opcache_get_status() can be 
used to
enumerate cached scripts, making exploitation even easier.

The software's documentation does not mention the issue, so most users 
see no reason not to enable OPCache on a shared server:

Original reporter in bug #67481 closed his bug report stating "It turns 
this is not a bug, it is the behaviour that is expected when 
opcache.use_cwd is
set to zero," but the same behavior occurs when opcache.use_cwd is 
unless scripts are invoked with relative paths. Absolute paths are 
used by web servers and web applications.

I've proposed a fix in bug #69090 with patch linked below.

I have point-and-click proof of concept exploit scripts but I plan to 
the PHP project a few more days to patch the issue.


In PHP 5.6, the problem is in cache key construction in

In PHP 7.0, equivalent code is in accel_make_persistent_key():

Please let me know if more details are needed.


Powered by blists - more mailing lists

Please check out the Open Source Software Security Wiki, which is counterpart to this mailing list.

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.