CVE-2015-8994
High · 7.5CVSS
7.5
EPSS
2.9%
Published
Mar 2, 2017
CISA due date
—
Cloudanix analysis
On servers that let many different customers run their own programs, a caching feature meant to speed things up could let one customer secretly read or run another customer's private code and steal its passwords or data.
- Exploitation
- Remote Authenticated
- Attacker needs
- Low Privilege
- Complexity
- Moderate
- Impact
- Data Exposure
- Component
- Library
- Class
- Authorization Bypass
- Remediation
- Upgrade
- Effort
- Medium
- Patch risk
- Low
What it actually does
In PHP SAPIs using apache2handler or php-fpm with OpCache, child processes inherit a shared memory descriptor from the parent, allowing any process to retrieve and execute opcode cached under a filename key regardless of the script owner's EUID-enforced permissions.
Why it matters to the business
Attackers on shared hosting can read or execute other tenants' PHP scripts, exposing configuration secrets, database credentials, and application logic, which can lead to full account compromise and data breaches in multi-tenant environments.
How an attack unfolds
An attacker uploads or guesses a target script's filename on a shared host, triggers OpCache lookup via a crafted request, and retrieves the cached bytecode that was written by another user's process, bypassing filesystem permissions; the long-published flaw with public exploits increases risk for unpatched shared-hosting fleets.
How to fix it
Upgrade PHP to versions after 5.6.28 or 7.0.13 and enable opcache.validate_permission=1; for the listed Alpine packages apply the provided fixed versions of libmad where applicable, or disable OpCache in multi-tenant setups if immediate patching is not possible.
How to confirm the fix worked
Confirm opcache.validate_permission=1 is set in php.ini, verify PHP version is newer than the vulnerable range, and test that separate EUID processes cannot retrieve each other's cached opcode via filename collision checks.
Typical attack path
- Identify shared-hosting server using mod_php or php-fpm with OpCache enabled
- Guess or discover target script filename via directory listing or error messages
- Issue HTTP request that causes OpCache to serve the cached opcode under that filename
- Execute or inspect sensitive code and configuration data from the returned bytecode
How to detect it
Review web server and PHP-FPM logs for repeated requests to guessed script paths, inspect OpCache statistics for unexpected cache hits across user boundaries, and search process listings or shared-memory segments owned by the parent PHP process for anomalies.
What your security team should do
- Prioritize patching all PHP instances on shared hosting within 30 days given public exploit availability
- Enable opcache.validate_permission=1 and audit multi-tenant configurations for EUID separation
- Monitor EPSS trend and re-assess if new threat actor activity emerges
The record
An issue was discovered in PHP 5.x and 7.x, when the configuration uses apache2handler/mod_php or php-fpm with OpCache enabled. With 5.x after 5.6.28 or 7.x after 7.0.13, the issue is resolved in a non-default configuration with the opcache.validate_permission=1 setting. The vulnerability details are as follows. In PHP SAPIs where PHP interpreters share a common parent process, Zend OpCache creates a shared memory object owned by the common parent during initialization. Child PHP processes inherit the SHM descriptor, using it to cache and retrieve compiled script bytecode ("opcode" in PHP jargon). Cache keys vary depending on configuration, but filename is a central key component, and compiled opcode can generally be run if a script's filename is known or can be guessed. Many common shared-hosting configurations change EUID in child processes to enforce privilege separation among hosted users (for example using mod_ruid2 for the Apache HTTP Server, or php-fpm user settings). In these scenarios, the default Zend OpCache behavior defeats script file permissions by sharing a single SHM cache among all child PHP processes. PHP scripts often contain sensitive information: Think of CMS configurations where reading or running another user's script usually means gaining privileges to the CMS database.
Affected packages
| Ecosystem | Package | Introduced | Fixed |
|---|---|---|---|
| SUSE:Linux Enterprise Module for Web and Scripting 12 | php5 | 0 | 5.5.14-99.1 |
| SUSE:Linux Enterprise Module for Web and Scripting 12 | php7 | 0 | 7.0.7-38.1 |
| SUSE:Linux Enterprise Software Development Kit 12 SP1 | php5 | 0 | 5.5.14-99.1 |
| SUSE:Linux Enterprise Software Development Kit 12 SP1 | php7 | 0 | 7.0.7-38.1 |
| SUSE:Linux Enterprise Software Development Kit 12 SP2 | php5 | 0 | 5.5.14-99.1 |
| SUSE:Linux Enterprise Software Development Kit 12 SP2 | php7 | 0 | 7.0.7-38.1 |
| Ubuntu:14.04:LTS | php5 | 0 | 5.5.9+dfsg-1ubuntu4.22 |
| Ubuntu:16.04:LTS | php7.0 | 0 | 7.0.15-0ubuntu0.16.04.2 |
| Ubuntu:16.04:LTS | php7.0 | 0 | 7.0.22-0ubuntu0.16.04.1 |
Related vulnerabilities
- CVE-2017-16642 In PHP before 5.6.32, 7.x before 7.0.25, and 7.1.x before 7.1.11, an error in the date… Also affects php5
- CVE-2017-12933 The finish_nested_data function in ext/standard/var_unserializer.re in PHP before 5.6.31… Also affects php5
- CVE-2017-7890 The GIF decoding function gdImageCreateFromGifCtx in gd_gif_in.c in the GD Graphics… Also affects php5
- CVE-2016-10166 Integer underflow in the _gdContributionsAlloc function in gd_interpolation.c in the GD… Also affects php5
- CVE-2016-6911 The dynamicGetbuf function in the GD Graphics Library (aka libgd) before 2.2.4 allows… Also affects php5
- CVE-2016-10158 The exif_convert_any_to_int function in ext/exif/exif.c in PHP before 5.6.30, 7.0.x… Also affects php5
- CVE-2016-10161 The object_common1 function in ext/standard/var_unserializer.c in PHP before 5.6.30… Also affects php5
- CVE-2016-7478 Zend/zend_exceptions.c in PHP, possibly 5.x before 5.6.28 and 7.x before 7.0.13, allows… Also affects php5