Log4Shell: Lua + Nginx Mitigation

John H Patton
Level Up Coding
Published in
3 min readDec 13, 2021

--

Prevent requests from reaching a vulnerable java application [CONFIG]

CODE UPDATED DECEMBER 15, 2021 @ 17:30 CST

Photo by Kyle Glenn on Unsplash

UPDATE

Additional patterns were added to the lua code.

CVE-2021–44228

If you were a sysadmin on any system with a java backend using log4j, this CVE may have ruined your Friday evening. Here are some details:

Blocking the bad traffic pattern is a quick win to buy some time to get the updated library in place. If you’re running nginx as a reverse proxy to the affected java application, this can easily be blocked with this method.

NOTE: the entire payload should be inspected: the line one request, the headers, and the body. Any part of the request could potentially be logged on a vulnerable java upstream.

Requirements

In order for this solution to work, the web host needs the following software:

  • Nginx, Nginx-Plus, or Openresty
  • Luajit 5.1 and all of the nginx lua dependencies if they are not installed

Lua Code

The easiest way to ensure nginx blocks all of the requests containing the log4shell payload is to inspect the entire request header and body payload in the rewrite phase. This will require extracting line 1, the request headers, and request body into a variable that can be inspected.

In each public facing server block, the following code will detect and block the affective pattern.

NOTE: this updates an nginx variable, $cve_2021_44228_log, used for logging and must be set in the server block that calls the block function.

The Details

The primary means by which this attack is used is to send the following example pattern:

${jndi:[protocol]://[attacker site]/a}

The part that makes this work is the “${jndi:” at the start, so looking for any substring in the request body or headers that match would catch this pattern. The “[protocol]” can be ldap, ldaps, rmi, dns, and various others, but is not needed for this mitigation. Additionally, variables can be used to obfuscate the pattern, like the following:

${${lower:j}ndi:[protocol]://[attacker site]/a}

Or even this:

${${::-j}${::-n}${::-d}${::-i}:[protocol]://[attacker site]/a}

To ensure this doesn’t slip through, the entire request payload must be inspected, including line 1, request headers, and request body if present.

To capture this as simply as possible, the first detection inspects the request payload non-recursively for “${jndi:” to catch the simplest pattern. If this matches, the request is denied.

The second detection consists of a recursive match separated into two parts. The first part captures the content of any “${}” group found in the payload. Example, the outer ${ } will be stripped, if found, to get at this:

${::-j}${::-n}${::-d}${::-i}:[protocol]://[attacker site]/a

The second part is then inspected against two patterns that will match any of the possible obfuscation methods within the attack string. If either match, the request is denied.

Complete Solution

Modify your configuration to add the following from an nginx-plus example built into the default configuration under /etc/nginx using the lua module above. Will also work with openresty or with opensource nginx with lua enabled.

NOTE: a log variable, $cve_2021_44228_log, was added to the default access log that can be used in the configuration, if desired. This variable needs to be set in the server block that uses the main log_format and calls the lua block function.

Main Nginx Configuration

The only adjustments from the default nginx.conf installed with nginx are the load_module directives and the log variable added to the log_format directive.

Include: Lua Configuration

The following will enable the lua configuration and create an instance of the lua module for use in the request processor:

Include: Default Configuration

Example adjustment to the default.conf included with nginx that calls the block function in the lua module, with extra commented directives removed:

Good Luck!

I hope this helps. Ganbatte!

--

--