How security flaws in PHP's core can affect your application20 Jul 2017 by Dr. Johannes Dahse
Popular security vulnerabilities occur due to bad coding practices or coding mistakes. Often a single missing character or incautiously used language feature opens the gates for an external attacker. But even when all best practices for secure programming are carefully adhered to, a PHP application’s source code is only as secure as the PHP interpreter it runs on. In this post, we will see how memory corruption bugs in the PHP core itself can affect an application’s security.
PHP Version Usage
At the time of writing, the statistics from W3Techs show that 93% of all PHP websites use PHP version 5, and only about 6% use its new successor PHP 7. For each of those major PHP versions several release branches are maintained. Each release branch is actively supported for two years and then for one additional year only with security fixes (see Figure 1).
For the popular PHP version 5, the release branches 5.6 (28.8%), 5.4 (22.9%) and 5.3 (22.4%) are commonly installed (see Figure 2). However, only PHP 5.6 is still supported with security fixes meaning that the remaining 71.2% of all PHP 5 websites run with an unsupported version.
The supported PHP 5.6 installations are not all secure though. Every patch release in the past fixed critical security issues in PHP’s core. But only 62% of all 5.6 installations run the latest patch version 5.6.30 (see Figure 3) released in January 2017. For PHP 7, about 70% of all websites run the latest version. As a result, about 79% of all PHP websites run at the moment on a vulnerable PHP interpreter.
There are various reasons why companies do not or cannot update their PHP installation. Oftentimes, different production, development, and testing environments would require simultanuous updates while changes or deprecations in the PHP language risk to break the code. In the following, we have a closer look at the security implications of outdated PHP versions.
Memory Corruption in PHP Features
PHP is a high-level scripting language that does not require custom management of data memory. Hence, PHP code itself is not affected by memory corruption bugs. Instead, the memory management is handled by the PHP interpreter that executes the PHP code on the web server. This interpreter is written in the C language and it can be affected by memory related security bugs. In fact, the PHP core comes with over 5,700 documented built-in functions and classes. If one of these features’ internal implementation is affected by a memory corruption flaw and this feature is invoked from the PHP code, then this security issue can be exploited by an attacker through the PHP application (see Figure 2). Depending on the type and occurence of the security issue in the feature’s implementation and its usage in the PHP code, this can lead to the remote execution of arbitrary code on the targeted web server and a full server compromise.
Since the beginnings of the PHP language, critical security issues were found in the vast variety of built-in features and even in the PHP handler itself that are remotely exploitable. In 2010, this escalated in the Month of PHP Security where a new memory corruption bug in PHP was released on a daily bases. Today, the CVE database documents over 500 known security issues in different PHP core versions. But how critical and exploitable are these security vulnerabilities in reality?
A Case Study: CVE-2016-5773
In July 2016, friends of RIPS Technologies participated in the bug bounty program of an adult video platform. In a blackbox analysis they detected serialized data that was undoubtedly passed into the PHP built-in function unserialize(). Since no other way of exploitation was effective, they decided to fuzz PHP’s internal feature implementation instead. A use-after-free vulnerability in PHP’s garbage collector was then detected that can be remotely triggered via the unserialize() call. The exploitation of this PHP internal security issue resulted in a remote code execution on the server and, after disclosing the issue to the vendor, a $20,0000 bug bounty. The incident demonstrated strikingly that although the PHP code of the application was not exploitable, a vulnerability in PHP’s core can still lead to a compromise. Similar security vulnerabilities can hide in all kinds of PHP features.
Recent Examples of Affected Features
|Feature||Affected PHP Versions||Vulnerability Type||Reference|
|unserialize()||< 7.0.15, < 7.1.1||Integer Overflow||CVE-2017-5340|
|wddx_deserialize()||< 7.0.15, < 7.1.1||NULL pointer dereference||CVE-2016-10162|
|curl_escape()||< 7.0.10||Buffer Overflow||CVE-2016-7134|
|str_pad()||< 7.0.4||Integer Overflow||CVE-2016-4537|
|utf8_encode()||< 7.0.4||Integer Overflow||CVE-2016-4345|
|imagerotate()||< 5.5.31, < 5.6.16, < 7.0.1||Incorrect Buffer Size||CVE-2016-1903|
Automated Detection of Exploitable Features
A remaining challenge for developers and security auditors is to keep track which PHP features are unsafe to use for which PHP version. With the help of RIPS it is now possible to detect exactly those vulnerable features that are exposed to attackers. For this purpose, the exact PHP version can be specified when initiating a new security scan in RIPS (see Figure 5).
Our analysis engine will then analyze all calls to built-in functions and methods that are known to be affected by security issues for the given PHP version. To prevent false alerts, RIPS does not just heuristically report the usage of possibly affected features. Instead, it uses its precise taint analysis in order to report only those affected features in the code that can be actually exploited by an attacker. For example, a built-in function that is affected by a buffer overflow vulnerability is only reported when an attacker is indeed able to pass overly long strings into the affected parameter.
RIPS highlights the vulnerable data flow of user input into the affected PHP feature and provides further information about the vulnerability type and its risks. Subsequently the security issue can be resolved by restricting the user input that is passed into the feature or by removing the vulnerable feature completely.
PHP is frequently updated in order to fix critical security issues in its core. In order to fully protect your application against adversaries, staying ahead of the arms race and applying security patches is crucial. Even if your code is securely written, leveraged PHP features may be still vulnerable to attacks. When legacy obligations or complex production environments prohibit regular patches, RIPS is the first code analysis solution that helps to automatically detect exploitable PHP features so that these can be disarmed.