On 9 April 2022, security vulnerabilities in the NGINX LDAP reference implementation were publicly shared. We have determined that only the reference implementation is affected. NGINX Open Source and NGINX Plus are not themselves affected, and no corrective action is necessary if you do not use the reference implementation.
The NGINX LDAP reference implementation uses Lightweight Directory Access Protocol (LDAP) to authenticate users of applications being proxied by NGINX. It is published as a Python daemon and related NGINX configuration at https://github.com/nginxinc/nginx-ldap-auth, and its purpose and configuration are described in detail on our blog.
Deployments of the LDAP reference implementation are affected by the vulnerabilities if any of the following conditions apply. Below we further discuss the conditions and how to mitigate them:
Note: The LDAP reference implementation is published as a reference implementation and describes the mechanics of how the integration works and all of the components required to verify the integration. It is not a production‑grade LDAP solution. For example, there is no encryption of the username and password used for the sample login page, and security notices call this out.
The primary way to configure the LDAP reference implementation is with a number of proxy_set_header
directives as detailed in the sample configuration and the documentation. However, the configuration parameters can also be set on the command line that initializes the Python daemon (nginx-ldap-auth-daemon.py).
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 any extraneous request headers are ignored during authentication by adding the following configuration to the location
=
/auth-proxy
block in the NGINX configuration (nginx-ldap-auth.conf in the repo).
location = /auth-proxy {
# ...
proxy_pass_request_headers off;
proxy_set_header Authorization $http_authorization; # If using Basic auth
# ...
}
As in Condition 1, an attacker can pass specially crafted HTTP request headers to override certain configuration parameters, if they were not set in the configuration. For example, the LDAP search template might be overridden if not explicitly set in the configuration. This is defended in the same way as Condition 1, by adding the following configuration to the location
=
/auth-proxy
block in the NGINX configuration.
location = /auth-proxy {
# ...
proxy_pass_request_headers off;
proxy_set_header Authorization $http_authorization; # If using Basic auth
# ...
}
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. The backend daemon in the LDAP reference implementation will be updated in this way in due course.
We thank Lucas Verney, valodzka, and @_Blue_hornet for highlighting these security vulnerabilities.
"This blog post may reference products that are no longer available and/or no longer supported. For the most current information about available F5 NGINX products and solutions, explore our NGINX product family. NGINX is now part of F5. All previous NGINX.com links will redirect to similar NGINX content on F5.com."