Path Traversal: '../filedir'
Description
Path Traversal: '../filedir' is a specific variant of path traversal vulnerability where software accepts input containing "../" sequences that are not properly neutralized, allowing attackers to traverse outside an intended directory by specifying a relative path to a parent directory followed by a target file or directory name. This vulnerability specifically addresses the common attack pattern where the "../" sequence is used as a prefix to access files in parent directories. The attack exploits the standard Unix/Linux convention where ".." refers to the parent directory, enabling attackers to climb up the directory tree from the application's working directory to access sensitive system files, configuration data, or other protected resources.
Risk
This vulnerability enables attackers to escape the intended directory confinement by using the parent directory reference "../" followed by a path to sensitive files. Applications that construct file paths from user input without sanitizing these traversal sequences expose their entire readable filesystem to potential attackers. Critical files such as /etc/passwd, application configuration files with database credentials, private keys, and source code become accessible. The simplicity and effectiveness of this attack pattern makes it one of the most commonly exploited file system vulnerabilities. When combined with write capabilities, attackers can potentially modify system configurations or plant malicious files.
Solution
Implement strict input validation that detects and rejects any input containing "../" sequences or their encoded variants including URL encoding (%2e%2e%2f), double URL encoding, and Unicode representations. Use canonical path resolution functions to convert all paths to absolute form and verify the resulting path remains within permitted directories before performing any file operations. Apply an allowlist approach where only specific, pre-defined file names or identifiers are accepted rather than arbitrary paths. Deploy the application with minimal filesystem privileges and consider using chroot jails or containers to limit the accessible filesystem scope as defense in depth.
Common Consequences
| Impact | Details |
|---|---|
| Confidentiality | Scope: Confidentiality Attackers can access sensitive files outside the intended directory by using "../filedir" patterns, exposing configuration files, credentials, source code, and system information. |
| Integrity | Scope: Integrity If write operations accept traversal sequences, attackers can modify or create files in unintended locations, potentially injecting malicious code or altering configurations. |
| Availability | Scope: Availability Critical system or application files could be overwritten or deleted through path traversal, causing service disruption or system failure. |
| Access Control | Scope: Access Control Access to credential files or authentication data via path traversal can lead to privilege escalation and unauthorized access to protected systems. |
Example Code + Solution Code
The following example demonstrates a vulnerable C application that reads files based on user input:
Vulnerable Code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BASE_DIR "/var/www/documents/"
#define MAX_PATH 512
void read_document(const char *filename) {
char filepath[MAX_PATH];
FILE *file;
char buffer[1024];
// VULNERABLE: Direct concatenation without validation
snprintf(filepath, MAX_PATH, "%s%s", BASE_DIR, filename);
// Attacker can use: ../../../etc/passwd
file = fopen(filepath, "r");
if (file == NULL) {
printf("Error: File not found\n");
return;
}
while (fgets(buffer, sizeof(buffer), file) != NULL) {
printf("%s", buffer);
}
fclose(file);
}
int main(int argc, char *argv[]) {
if (argc < 2) {
printf("Usage: %s <filename>\n", argv[0]);
return 1;
}
read_document(argv[1]);
return 0;
}
This code directly concatenates user input with the base directory path. An attacker providing "../../../etc/passwd" causes the application to read /var/www/documents/../../../etc/passwd, which resolves to /etc/passwd.
Fixed Code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <errno.h>
#define BASE_DIR "/var/www/documents"
#define MAX_PATH PATH_MAX
int contains_traversal(const char *input) {
// Check for various traversal patterns
if (strstr(input, "..") != NULL) return 1;
if (strstr(input, "./") != NULL) return 1;
if (strchr(input, '\0') != input + strlen(input)) return 1; // null byte
return 0;
}
int is_safe_path(const char *base, const char *filepath) {
char resolved_base[MAX_PATH];
char resolved_path[MAX_PATH];
// Resolve both paths to canonical form
if (realpath(base, resolved_base) == NULL) {
return 0;
}
if (realpath(filepath, resolved_path) == NULL) {
return 0;
}
// Verify the resolved path starts with the base directory
size_t base_len = strlen(resolved_base);
if (strncmp(resolved_path, resolved_base, base_len) != 0) {
return 0;
}
// Ensure it's actually a subdirectory (not just prefix match)
if (resolved_path[base_len] != '/' && resolved_path[base_len] != '\0') {
return 0;
}
return 1;
}
void read_document(const char *filename) {
char filepath[MAX_PATH];
FILE *file;
char buffer[1024];
// First line of defense: reject obvious traversal attempts
if (contains_traversal(filename)) {
fprintf(stderr, "Error: Invalid filename (traversal detected)\n");
return;
}
// Validate filename contains only allowed characters
for (size_t i = 0; i < strlen(filename); i++) {
char c = filename[i];
if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
(c >= '0' && c <= '9') || c == '.' || c == '_' || c == '-')) {
fprintf(stderr, "Error: Invalid character in filename\n");
return;
}
}
snprintf(filepath, MAX_PATH, "%s/%s", BASE_DIR, filename);
// Critical: Verify resolved path is within base directory
if (!is_safe_path(BASE_DIR, filepath)) {
fprintf(stderr, "Error: Access denied (path outside allowed directory)\n");
return;
}
file = fopen(filepath, "r");
if (file == NULL) {
fprintf(stderr, "Error: File not found\n");
return;
}
while (fgets(buffer, sizeof(buffer), file) != NULL) {
printf("%s", buffer);
}
fclose(file);
}
int main(int argc, char *argv[]) {
if (argc < 2) {
printf("Usage: %s <filename>\n", argv[0]);
return 1;
}
read_document(argv[1]);
return 0;
}
The fixed code implements multiple layers of defense: explicit checking for traversal sequences like "..", character allowlisting for filenames, and canonical path resolution using realpath() to verify the final resolved path remains within the intended base directory.
Exploited in the Wild
Apache HTTP Server Path Traversal (Global, 2021)
CVE-2021-41773 affected Apache HTTP Server 2.4.49 where path traversal using "../" sequences with URL encoding (%2e) allowed attackers to access files outside the document root. If CGI scripts were enabled, this also permitted remote code execution. The vulnerability was actively exploited in the wild immediately after disclosure, affecting thousands of servers before patches could be applied. A subsequent fix in 2.4.50 was found to be incomplete, leading to CVE-2021-42013.
GitLab Arbitrary File Read (GitLab Instances, 2023)
CVE-2023-2825 in GitLab CE/EE versions 16.0.0 allowed unauthenticated attackers to read arbitrary files on the server through a path traversal vulnerability. Attackers could use "../" sequences to escape intended directories and access sensitive configuration files, potentially including GitLab's secrets file containing encryption keys and database credentials. The vulnerability affected the handling of attachments in public projects.
Zyxel Firewall Path Traversal (Network Infrastructure, 2022)
CVE-2022-30525 affected Zyxel firewalls where path traversal via "../" sequences combined with command injection allowed unauthenticated remote attackers to achieve code execution. The vulnerability impacted multiple Zyxel firewall products used to protect enterprise networks, with active exploitation observed targeting network perimeter devices.
Tools to test/exploit
-
Burp Suite — comprehensive web security testing tool with built-in path traversal payloads including "../filedir" patterns and various encoding techniques to bypass filters.
-
dotdotpwn — specialized directory traversal fuzzer that tests numerous "../" payload variations including encoded forms, deep traversal depths, and platform-specific sequences.
-
FFUF — fast web fuzzer that can be used with path traversal wordlists to systematically test for "../filedir" style vulnerabilities across multiple parameters.
CVE Examples
-
CVE-2021-41773 — Apache HTTP Server path traversal via encoded "../" sequences allowing file access and potential RCE.
-
CVE-2023-2825 — GitLab arbitrary file read through "../" path traversal in attachment handling.
-
CVE-2022-30525 — Zyxel firewall path traversal combined with command injection for unauthenticated RCE.
-
CVE-2020-5410 — Spring Cloud Config Server path traversal via "../" allowing access to arbitrary files.
References
-
MITRE. "CWE-24: Path Traversal: '../filedir'." Common Weakness Enumeration. https://cwe.mitre.org/data/definitions/24.html
-
OWASP. "Path Traversal." OWASP Foundation. https://owasp.org/www-community/attacks/Path_Traversal
-
PortSwigger. "File path traversal." Web Security Academy. https://portswigger.net/web-security/file-path-traversal
-
Checkmarx. "What is Path Traversal?" https://checkmarx.com/glossary/path-traversal/