On April 9, hacking group BlueHornet tweeted about an experimental exploit for NGINX 1.18 and promised to warn companies affected by it. On April 10, BlueHornet claimed to have breached the China branch of UBS Securities using the NGINX vulnerability.

Tweet

All we learned on Twitter was that a new zero-day vulnerability in the NGINX web server existed and had been publicly revealed. The vulnerability could allow remote code execution (RCE) on a vulnerable system.

But on April 11, NGINX responded with an article saying that after investigating the issue, it had found it only affects reference implementations. Specifically, the NGINX LDAP reference implementation which uses LDAP to authenticate users of applications being proxied by NGINX.

NGINX

NGINX is an open-source HTTP and reverse proxy server, a mail proxy server, and a generic TCP/UDP proxy server. When it was first released, NGINX was used mostly for serving static files, but since then, it has grown into a complete web server that deals with the entire spectrum of server tasks. NGINX has surpassed Apache in popularity due to its lightweight footprint and its ability to scale easily on minimal hardware. According to specialists, NGINX can run thousands of connections of static content simultaneously and is 2.5 times faster than Apache.

LDAP

Lightweight directory access protocol (LDAP) is a protocol that makes it possible for applications to query user information rapidly. Companies store usernames, passwords, email addresses, printer connections, and other static data within directories. LDAP is an open, vendor-neutral application protocol for accessing and maintaining that data. LDAP can also tackle authentication, so users can sign on just once and access many different files on the server.

The NGINX LDAP reference implementation uses LDAP to authenticate users of applications proxied by NGINX. The reference implementation was announced in June 2015. The solution leverages the ngx_http_auth_request_module (Auth Request) module in NGINX and NGINX Plus, which forwards authentication requests to an external service. In the reference implementation, that service is a daemon called ldap‑auth. It’s written in Python and communicates with a LDAP authentication server.

NGINX and LDAP
Image courtesy of NGINX

The vulnerabilities

The primary way to configure the LDAP reference implementation is with a number of proxy_set_header directives. However, the configuration parameters can also be set on the command line that initializes the Python daemon. The vulnerabilities exist in the way unsanitized input can be used to change or set LDAP configuration parameters.

The NGINX blog specifies the circumstances that need to be fulfilled for the vulnerabilities to be exploited:

  • Command-line parameters are used to configure the Python daemon
  • There are unused, optional configuration parameters
  • LDAP authentication depends on specific group membership

Mitigation

NGINX provides mitigation recommendations for each of these conditions.

When configuration parameters are specified on the command line, an attacker can override some or all of them by passing specially crafted HTTP request headers. To protect against this, ensure that the corresponding configuration parameters have an empty value in the location = /auth-proxy block in the NGINX configuration.

Also ensure that any unused, optional parameters have an empty value in the location = /auth-proxy block in the NGINX configuration.

The Python daemon does not sanitize its inputs. Consequently, an attacker can use a specially crafted request header to bypass the group membership (memberOf) check and so force LDAP authentication to succeed even if the user being authenticated does not belong to the required groups. To mitigate against this, ensure that the backend daemon that presents the login form strips any special characters from the username field. In particular, it must remove the opening and closing parenthesis characters ( ) and the equal sign =, which all have special meaning for LDAP servers.

NGINX states that the backend daemon in the LDAP reference implementation will be updated to sanitize this type of input in due course.

And we have rounded up some additional advice.

Because LDAP extends to IoT devices, of which there are many more than IT devices, organizations running LDAP need to encrypt traffic using TLS certificates on IoT devices, keep the firmware up to date, and apply proper password management.

Make sure that you sanitize any input before it gets passed to the daemon.

Stay safe, everyone!