Addressing the PHP-FPM Vulnerability (CVE-2019-11043) with NGINX

Original: https://www.nginx.com/blog/php-fpm-cve-2019-11043-vulnerability-nginx/

A recently reported vulnerability, tracked as CVE-2019-11043, can affect websites that use PHP‑FPM to execute PHP pages. PHP‑FPM usage is particularly common at NGINX‑powered websites because NGINX does not have an in‑process PHP runtime. Instead, NGINX acts as a reverse proxy for application servers and process managers such as PHP‑FPM.

The vulnerability lies in PHP‑FPM itself, not NGINX, so the only guaranteed solution is to upgrade to the patched release (or later) of your PHP version: PHP 7.1.33, PHP 7.2.24, or PHP 7.3.11.

What Is the Nature of the Vulnerability?

NGINX communicates with PHP‑FPM using the FastCGI protocol. Each FastCGI message contains a set of environment variables. One of these, PATH_INFO, is derived from other request parameters. If its value is unexpectedly empty, this can ultimately cause memory corruption in the PHP‑FPM binary. It is possible to exploit this situation and make the PHP‑FPM binary run arbitrary commands on the local server.

This vulnerability can be triggered by a common NGINX configuration, whereby NGINX uses a regular expression in the fastcgi_split_path_info directive to split the request URI into two parts. One way to trigger the vulnerability is to embed a line break (%0a) or carriage return (%0d) character into the request URI, which is then not correctly handled by the regular expression.

Mitigating Against the Vulnerability

As mentioned above, the only certain way to address this vulnerability is to upgrade to the patched release (or later) of your PHP version: PHP 7.1.33, PHP 7.2.24, or PHP 7.3.11.

If you are not able to upgrade your PHP binary immediately, there are two partial mitigations you can make:

  1. Add a try_files directive to the NGINX configuration to verify that the $uri variable resolves to a file (the PHP script) and reject the request with code 404 (Not Found) if not:

    location ~ [^/]\.php(/|$) {
        fastcgi_split_path_info ^(.+?\.php)(/.*)$;
        fastcgi_param           PATH_INFO $fastcgi_path_info;
        try_files               $uri =404;
        #...
    }

    Note that this mitigation only works if NGINX and PHP‑FPM share the same docroot on the same host.

  2. Add a ModSecurity rule to block requests that contain the suspicious %0a or %0d character:

    SecRule REQUEST_URI "@rx %0(a|A|d|D)" "id:1,phase:1,t:lowercase,deny"

    This solution is described in the Wallarm’s original report about the vulnerability; it may cause false positives and an attacker might still find other ways to exploit the vulnerability.

Using a Different PHP Process Manager

Rather than rely on PHP‑FPM, you can use NGINX Unit to run your PHP applications. NGINX Unit is a high‑performance, open source application server and process manager that supports numerous languages and frameworks in addition to PHP. It can auto‑scale PHP applications in response to load, and concurrently run applications that use different PHP runtimes. We provide binaries, source, and Docker images for free.

See the NGINX Unit documentation for instructions on configuring and operating NGINX Unit for WordPress, a popular, high‑traffic, PHP‑powered application. The deployment takes advantage of the support for serving static files in NGINX Unit 1.11.0 and later.

Retrieved by Nick Shadrin from nginx.com website.