Vulnerability Analysis

Apache HTTP Server CVE-2021-41773: A Path Traversal Bug That Should Have Been Caught in Code Review

CVE-2021-41773 allowed path traversal and RCE on Apache HTTP Server 2.4.49. The fix was incomplete, leading to CVE-2021-42013 days later. A lesson in patching under pressure.

Alex
Security Researcher
6 min read

On October 4, 2021, Apache disclosed CVE-2021-41773, a path traversal vulnerability in Apache HTTP Server version 2.4.49. The bug was embarrassingly simple: a flaw in the URL normalization code allowed attackers to use URL-encoded path traversal sequences to escape the document root and read arbitrary files from the server. If mod_cgi or mod_cgid was enabled, it was remote code execution. Three days later, it turned out the patch was incomplete, and CVE-2021-42013 was assigned to the bypass. Two critical vulnerabilities in one week, in the most widely deployed web server on the planet.

The Vulnerability

Apache HTTP Server 2.4.49 introduced a change to the path normalization logic. The new code was supposed to prevent directory traversal attacks by resolving URL-encoded characters before checking the path against configured access controls. It didn't work.

The original exploit was straightforward:

GET /cgi-bin/.%2e/%2e%2e/%2e%2e/%2e%2e/etc/passwd HTTP/1.1

The %2e sequences are URL-encoded periods. The path /.%2e/ decodes to /../, which traverses up one directory. The normalization code in Apache 2.4.49 failed to catch this specific encoding pattern, allowing the traversal to escape the configured document root.

If the server had Require all granted configured for the document root (a common default) and CGI was enabled, the same technique could execute arbitrary commands:

POST /cgi-bin/.%2e/%2e%2e/%2e%2e/%2e%2e/bin/sh HTTP/1.1
Content-Type: application/x-www-form-urlencoded

echo Content-Type: text/plain; echo; id

This returned the output of the id command, running as the Apache user. Full remote code execution, no authentication required.

The Botched Patch

Apache released version 2.4.50 on October 4, the same day as the CVE-2021-41773 disclosure. The patch attempted to fix the path normalization by adding additional checks for the specific encoding pattern.

Within three days, researchers found that the patch was incomplete. By double-encoding the path traversal sequences (%%32%65 instead of %2e), the fixed normalization code could be bypassed again. This was assigned CVE-2021-42013.

Apache released version 2.4.51 on October 7 to address the bypass. This meant organizations had to patch twice in one week — assuming they patched at all.

The root cause of both vulnerabilities was the same: the URL normalization code didn't handle all possible encodings of directory traversal characters. Instead of using a comprehensive normalization approach (fully decode, then validate), the code was pattern-matching specific encodings and missing edge cases.

The Scope of Exposure

Apache HTTP Server powers roughly 25% of all websites globally. However, CVE-2021-41773 only affected version 2.4.49, which had been released on September 15, 2021 — less than three weeks before the vulnerability was disclosed.

This limited the scope somewhat. Organizations that hadn't upgraded to 2.4.49 were not affected. But those that were running 2.4.49 were likely organizations that actively maintained their Apache installations, making this a case where being up-to-date actually increased risk.

Shodan scans shortly after disclosure identified thousands of Apache 2.4.49 servers exposed to the internet. Exploitation in the wild was confirmed within 24 hours of the initial disclosure.

Why This Bug Was Significant

Simplicity of Exploitation

No authentication, no special tools, no complex exploit chains. A single HTTP request could read files or execute commands. This is the kind of vulnerability that script kiddies can exploit with curl.

The Double-Patch Problem

Having to patch twice in one week erodes confidence in the patching process. Organizations that rushed to deploy 2.4.50 discovered they were still vulnerable and had to go through the entire change management process again for 2.4.51. Some gave up and rolled back to 2.4.48 instead.

A Regression, Not a Legacy Bug

This vulnerability was introduced in version 2.4.49. It didn't exist in earlier versions. This means the development process for one of the most critical pieces of infrastructure on the internet failed to catch a basic path traversal flaw. No fuzzing, no security review, and no automated testing caught it before release.

CGI Is Still Everywhere

Many assumed CGI was a relic of the 1990s. The exploitation of CVE-2021-41773 revealed that mod_cgi and mod_cgid are still enabled on a surprising number of production servers, often by default. Legacy CGI scripts continue to run on servers worldwide, expanding the attack surface from file read to remote code execution.

Lessons Learned

1. URL Normalization Is Deceptively Hard

Path traversal prevention requires comprehensive input normalization. You can't enumerate all possible encoding patterns — you need to fully decode the input, normalize the path, and then validate it. Any approach based on pattern matching will eventually be bypassed.

2. New Releases Need Security Testing

Version 2.4.49 introduced a regression that created a critical vulnerability. Every release, even minor ones, should undergo security-focused testing including fuzzing of URL handling, path traversal checks, and encoding bypass attempts.

3. Default Configurations Matter

The vulnerability was exploitable for RCE only when CGI was enabled and specific access controls were in place. But these were common default configurations. Secure defaults — disabling CGI, restricting directory access — would have reduced the impact significantly.

4. Have a Rollback Plan

Organizations that could quickly roll back to Apache 2.4.48 were able to mitigate the vulnerability immediately while waiting for a reliable fix. Those without rollback capabilities were stuck choosing between a known-vulnerable version and an incompletely-patched version.

The CISA Response

CISA added CVE-2021-41773 to its Known Exploited Vulnerabilities (KEV) catalog, requiring federal agencies to patch within specific timeframes. The vulnerability was also flagged in multiple threat intelligence feeds as actively exploited by both targeted threat actors and opportunistic scanners.

The rapid response from CISA reflected the severity of the vulnerability and the widespread use of Apache HTTP Server in government infrastructure.

How Safeguard.sh Helps

Safeguard.sh provides the capabilities needed to respond rapidly to vulnerabilities like CVE-2021-41773:

  • Real-Time Vulnerability Correlation: When a new CVE is disclosed, Safeguard.sh immediately maps it against your software inventory, identifying every instance of the affected version across your environment.
  • Version Tracking: Safeguard.sh tracks exact software versions, so you can instantly determine whether you're running the vulnerable 2.4.49, the incompletely-patched 2.4.50, or the fixed 2.4.51.
  • Patch Verification: After remediation, Safeguard.sh verifies that the correct version is deployed, catching cases where rollbacks or failed deployments leave systems vulnerable.
  • Configuration Analysis: Safeguard.sh helps identify risky configurations like enabled CGI modules that expand the impact of vulnerabilities from information disclosure to remote code execution.

CVE-2021-41773 showed that even the most scrutinized open-source projects can ship critical vulnerabilities. Safeguard.sh ensures you have the visibility to respond in hours, not weeks.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.