CVE-2019-11043

Remote Code Execution
Affects
PHP
in
PHP
No items found.
Versions
<7.1.33, >=7.2.0 <7.2.24, >=7.3.0 <7.3.11

Patch Available.

Exclamation circle icon
Patch Available

This Vulnerability has been fixed in the Never-Ending Support (NES) version offered by HeroDevs.

Overview

PHP is a general-purpose scripting language used mostly for web development. It runs behind web servers through server APIs such as Apache mod_php and PHP-FPM, and powers content management systems and frameworks such as WordPress, Drupal, Moodle and Laravel. PHP-FPM is PHP's FastCGI process manager, the server API that runs PHP behind web servers such as nginx.

A Remote Code Execution (RCE) vulnerability (CVE-2019-11043) has been identified in the request setup code of PHP-FPM, which allows a remote, unauthenticated attacker to make PHP-FPM write outside the buffer that holds the request's PATH_INFO value when the web server splits PATH_INFO with a regular expression, as nginx's fastcgi_split_path_info does, and so possibly to execute code on the server. PHP tracks this issue as bug #78599.

Per MITRE CWE-787: The product writes data past the end, or before the beginning, of the intended buffer.

This issue affects PHP 7.1 before 7.1.33, PHP 7.2 before 7.2.24 and PHP 7.3 before 7.3.11, as well as the End-of-Life release lines PHP 5.6 and 7.0 through their final releases (5.6.40 and 7.0.33).

Details

Module Info

Vulnerability Info

This High-severity vulnerability is found in the FPM server API of PHP 7.1 before 7.1.33, 7.2 before 7.2.24 and 7.3 before 7.3.11, and in the End-of-Life PHP 5.6 and 7.0 release lines, which never received the upstream fix. The PHP project scores it 8.7 under CVSS 3.1 (CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:N).

When a web server passes a request to PHP-FPM, init_request_info() works out which script to run and which part of the path is PATH_INFO. It strips path components from the translated path until it finds a real file, records how many characters it removed in slen, and then locates the matching tail of the PATH_INFO value the web server sent. In PHP 7.1.32, that code reads:

int ptlen = strlen(pt);
int slen = len - ptlen;
int pilen = env_path_info ? strlen(env_path_info) : 0;
int tflag = 0;
char *path_info;
if (apache_was_here) {
    /* recall that PATH_INFO won't exist */
    path_info = script_path_translated + ptlen;
    tflag = (slen != 0 && (!orig_path_info || strcmp(orig_path_info, path_info) != 0));
} else {
    path_info = env_path_info ? env_path_info + pilen - slen : NULL;
    tflag = (orig_path_info != path_info);
}

The code assumes PATH_INFO is at least slen characters long. With nginx's fastcgi_split_path_info, a crafted request can make PATH_INFO come out empty while the stripped part is not. pilen - slen is then negative and path_info points before the start of the PATH_INFO buffer. The code that follows temporarily writes a NUL byte at path_info[0], so it writes into memory before the buffer. According to the CVE record, that memory is space PHP-FPM reserves for FastCGI protocol data, which opens the possibility of remote code execution, and the record references a public exploit that does this.

Exploitation needs PHP-FPM behind nginx, or another web server, configured to split PATH_INFO with a regular expression such as fastcgi_split_path_info and to pass it to PHP, which HeroDevs' analysis describes as a common setup. The attacker needs no account and only sends HTTP requests. Servers that do not set PATH_INFO this way, and PHP that runs under other server APIs such as Apache mod_php or the CLI, are not exposed.

The fix uses the PATH_INFO offset only when it lies inside the value, and otherwise leaves path_info unset so the NUL write is skipped:

path_info = (env_path_info && pilen > slen) ? env_path_info + pilen - slen : NULL;
tflag = path_info && (orig_path_info != path_info);

Mitigation

The PHP project publishes security fixes only for its supported release lines. PHP 5.6 and 7.0 are End-of-Life and will not receive any public updates to address this issue.

Until an upgrade is possible, make nginx confirm that the script exists before it passes the request to PHP-FPM, for example by adding try_files $fastcgi_script_name =404; after fastcgi_split_path_info, or stop splitting PATH_INFO if the application does not need it.

Users of the affected components should apply one of the following mitigations:

  • Upgrade to PHP 7.1.33, 7.2.24, 7.3.11, or later.
  • Leverage a commercial support partner like HeroDevs (NES for PHP) for post-EOL security support.

Credits

Vulnerability Details
Severity
Level
CVSS Assessment
Low
>=0 <4
Medium
>=4 <6
High
>=6 <8
Critical
>=8 <10
High
ID
CVE-2019-11043
PROJECT Affected
PHP
Versions Affected
<7.1.33, >=7.2.0 <7.2.24, >=7.3.0 <7.3.11
NES Versions Affected
Published date
October 28, 2019
≈ Fix date
October 24, 2019
Fixed in
Category
Remote Code Execution
Vex Document
Download VEXHow do I use it?
Sign up for the latest vulnerability alerts fixed in
PHP
Rss feed icon
Subscribe via RSS
or

By submitting the form I acknowledge receipt of our Privacy Policy.

Thanks for signing up for our Newsletter! We look forward to connecting with you.
Oops! Something went wrong while submitting the form.