CWE-25 is a path traversal variant built around the sequence "/../". The product builds a file path from external input, meant to stay inside a restricted directory, and fails to neutralize that sequence so the path resolves outside it.
MITRE notes why the variant exists. Sometimes a program checks for "../" at the beginning of the input. A leading slash puts the "../" one step later, and the check never sees it.
How it happens
Picture a filter that rejects any input starting with "../". The attacker sends "/../" instead. The filter passes it, the application joins it to the base directory, and the operating system resolves the dots upward.
The lesson is that string checks on the raw input are weak. The operating system decides what a path means, so the application has to ask the same question after the path is built.
What an attacker gains
The record lists reading files or directories and modifying files or directories. That covers configuration, credentials, source code, and anything the process can write.
MITRE gives one observed case, CVE-2022-20775, where a cloud management tool let attackers bypass a restricted shell using sequences like "/../" in the USER environment variable.
How to find it
Static analysis can trace external input into file operations and flag paths that are not normalized. In review, search for file open calls whose argument includes request data.
How to fix it
Resolve first, then compare.
import os
BASE = os.path.realpath("/srv/app/files")
def safe_path(user_input):
target = os.path.realpath(os.path.join(BASE, user_input))
if os.path.commonpath([BASE, target]) != BASE:
raise ValueError("path escapes base directory")
return target
Better still, accept an identifier and map it to a file yourself, so users never supply a path.
Quick check
Why does a leading-slash trick beat a prefix check?
The check tests only the start of the string. Moving the dots later leaves the start clean, while the final resolved path still climbs out of the directory.