Single-Level Directory Traversal to a Named Sensitive Config/Secret File
Some file-serving or upload features restrict access to one folder but forget that a single '../' can step out of it. Attackers use this to jump straight to config or secret files sitting just outside the sandbox, exposing API keys and credentials.
How the attack works
An application serves files from a subdirectory, like web_assets/, and expects requests to stay inside it. The attacker requests a path using exactly one '../' segment, such as file=web_assets/../config.json, which escapes the subdirectory into its parent. There, they target a specifically named sensitive file - config.json, .env, secrets.json, credentials.json, wp-config.php, id_rsa, .htpasswd, or settings.py. This one-hop escape is enough because the app's own secrets typically live one level above the folder it serves publicly.
Netzilo detection
Netzilo reports this behaviour when it is observed.
- Signature ID
- a4a94b08-d84f-450c-ad64-4108db5ff282
- Severity
- High
- CVEs
- CVE-2024-3234
Why it matters
Successful exploitation exposes API keys, database credentials, or other secrets that the application stores just outside its public-facing directory, as happened in a real chatbot tool where a single traversal leaked an OpenAI API key.
What you can do
- →Store configuration and secret files outside any directory reachable from a file-serving or upload endpoint, not just one level up.
- →Validate and canonicalize file paths on the server, rejecting any request containing '../' rather than only checking for deeper traversal chains.
- →Run file-serving components with a filesystem-level restriction (chroot, container mount, or OS permissions) so they cannot read files outside their intended folder even if path checks fail.
- →Audit third-party components (like bundled file-serving libraries) for known path traversal CVEs and keep them updated.
Known benign look-alikes
- A legitimate monorepo-relative reference that genuinely needs one '../' to reach a same-named local file that is not actually the app's secrets store
- Educational or changelog text discussing this exact CVE's PoC path as an example, not an actual tool-call argument
- Ordinary monorepo dotenv/config loading such as load_env(path='backend/../.env') or load_config(path='backend/../config.json') -- 'backend' (or any other ordinary source-code directory name) is not a recognized asset-serving/upload sandbox, so this rule no longer fires on it; it now requires the escaped directory to look like the kind of public file-serving sandbox the underlying CVE class actually describes