CVE-2022-30123 - Exploiting Sequence Injection in Rack’s Lint and CommonLogger for Shell Escape
In 2022, a critical vulnerability shook the Ruby web development world. Labeled CVE-2022-30123, this flaw affected Rack, a popular library that underpins most Ruby web frameworks—including Rails and Sinatra. In this long read, we’ll break down what happened, why it’s dangerous, show code examples, and even walk you through the process of exploiting it.
Exclusive: You’ll find this explanation in simple, direct language, with snippets and references for a deeper understanding.
What Is Rack and Why Should I Care?
Rack is the middleman between Ruby web applications and web servers like Puma or Unicorn. It handles HTTP requests and responses, providing “middleware” features like logging, request validation, and more.
If your Ruby or Rails app runs on the internet, chances are it uses Rack. That’s why vulnerabilities like CVE-2022-30123 are so scary—they put lots of web apps at risk.
What’s the Issue?
A sequence injection vulnerability exists in several versions of Rack (<2..9.1, <2.1.4.1, and <2.2.3.1). Specifically, the problem lives in the Rack::Lint and Rack::CommonLogger components.
If an attacker manages to inject a malicious sequence into HTTP headers or parameters, this bug can let them “escape” into the shell—possibly running arbitrary commands—when logging or processing inputs.
Why Is This Dangerous?
- Shell Escape: Attackers can break out of the intended application flow and run arbitrary system commands.
- Sensitive Contexts: Servers often run with high privileges, so exploits could lead to data compromises, server takeovers, or worse.
- Undetected: This type of bug often flies under the radar since it abuses logs or error-handling rather than direct input processing.
Proof-of-Concept Code Example
Let’s look at how this vulnerability could be triggered. Suppose you’re running a vulnerable Rack version and use Rack::CommonLogger to log incoming requests.
# Vulnerable Rack-based application
require 'rack'
require 'rack/commonlogger'
app = Rack::Builder.new do
use Rack::CommonLogger
run ->(env) { [200, { "Content-Type" => "text/plain" }, ["Hello world"]] }
end
Rack::Handler::WEBrick.run app
Now, what if an attacker sends a special sequence in the HTTP headers?
curl -H 'X-Forwarded-For: 127...1%A;cat /etc/passwd%' http://localhost:808/
Here, %A is a newline.
- Injected input may break out of logging context and execute extra shell commands, depending on server configuration.
Note: Exploitability can depend on downstream log processing—for example, if logs are piped to a shell command.
Malicious Header Injection
The attacker crafts a request with an HTTP header (such as X-Forwarded-For) containing newline or special characters.
Logger Mishandling
Rack::CommonLogger does not properly sanitize this input. It logs it directly, sometimes resulting in split log entries or command injection if logs are piped or processed by shell scripts.
Shell Escape
If logs are used by downstream shell scripts (perhaps for parsing or alerting), the injected sequence can break context and execute commands, like dumping /etc/passwd.
Suppose a server uses a shell script to scan logs for certain errors
grep "ERROR" /var/log/web.log | sh
If the log contains injected shell code, this script could run it by accident.
Links to Original References
- CVE entry on NVD
- Rack Security Advisory (GitHub)
- Rack Commit Patch
Final Thoughts
CVE-2022-30123 is a classic reminder that even little things like loggers shouldn’t blindly trust user input. If you maintain Ruby web apps, keep dependencies sharp and review how you handle anything coming from the outside—even in logs.
Feel free to share, discuss, and double-check your setups. Sometimes, the weakest link isn’t your main code, but what happens off to the side.
Timeline
Published on: 12/05/2022 22:15:00 UTC
Last modified on: 12/07/2022 04:38:00 UTC