T05 · Unauthorized Access and Privilege Escalation
- Location
scripts/pdf_extractor.py:10- Finding
Workspace Input Path Validation Can Be Bypassed
- Content
View full analysis
Vulnerability Details
File Location:
scripts/pdf_extractor.py, lines 10-13
Vulnerability Type: Improper path containment validation
Risk Level: MediumVulnerable Code:
python # SECURITY: Path traversal validation abs_input_path = os.path.abspath(input_path) if not abs_input_path.startswith(os.path.abspath(".")): print(f"SECURITY ERROR: Path traversal detected. Input path '{input_path}' resolves outside of workspace.") sys.exit(1)Technical Analysis
The code attempts to restrict PDF input files to the current workspace by comparing path strings with
startswith(). String-prefix matching does not prove that one filesystem path is contained within another.For example, if the workspace is
/tmp/app, the path/tmp/app-secret/document.pdfstarts with/tmp/appeven though it is located in a sibling directory. In addition,os.path.abspath()normalizes path syntax but does not resolve symbolic links. A symbolic link stored inside the workspace can therefore point to a PDF outside the workspace and still pass this validation.The subsequent
os.path.isfile(input_path)check only verifies that the supplied path resolves to a regular file. It does not establish that the resolved file remains inside the intended workspace.Attack Path
- The attacker identifies a readable PDF outside the intended workspace.
- The attacker supplies either:
- A path in a sibling directory whose name begins with the workspace path, or
- A symbolic link inside the workspace that points to the external PDF.
os.path.abspath()produces a path whose string passes thestartswith()check.os.path.isfile()follows the path or symbolic link and confirms that the target is a regular file.opendataloader_pdf.convert()reads and processes the external PDF.
Impact Assessment
Successful exploitation allows access to PDF files outside the intended workspace, subject to t ...[truncated 330 chars]
- Remediation
View remediation
Remediation Suggestions
Resolve the workspace and candidate paths to their canonical filesystem locations before checking containment. Use path-aware containment instead of string-prefix matching.
python from pathlib import Path workspace = Path.cwd().resolve() candidate = Path(input_path).resolve(strict=True) if not candidate.is_relative_to(workspace): raise ValueError("Input file must remain inside the workspace") if not candidate.is_file(): raise ValueError("Input path must reference a regular file")For Python versions without
Path.is_relative_to(), compare canonical paths withos.path.commonpath(). If symbolic links are unnecessary, explicitly reject them and consider validating each path component to prevent symlink-based redirection.
