T09 · Insecure Skill Coding Practices
- Location
scripts/fetch_paper.py:39- Finding
Predictable Output Files Allow Symlink-Based File Overwrite
- Content
View full analysis
Vulnerability Details
File Location:
scripts/fetch_paper.py, lines 39-42, 55-60, and 94-99
Vulnerability Type: Predictable temporary and output files with unsafe overwrite behavior
Risk Level: MediumVulnerable Code
python # Create filename from DOI safe_doi = doi.replace('/', '_').replace('\\', '_') pdf_filename = f"paper_{safe_doi}.pdf" pdf_path = output_path / pdf_filename temp_html = output_path / "temp_scihub.html"python curl_cmd = [ 'curl', '-L', sci_hub_url, '-H', 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36', '-o', str(temp_html), '-s' ]python curl_cmd = [ 'curl', '-L', pdf_url, '-H', 'User-Agent: Mozilla/5.0', '-o', str(pdf_path), '-s' ]Technical Analysis
The script stores intermediate HTML in the fixed filename
temp_scihub.htmland derives the final filename predictably from the user-supplied DOI. It then passes these paths tocurl -o, which opens existing destinations for writing and can follow symbolic links.The implementation does not verify whether either destination already exists, whether it is a symbolic link, or whether the output directory is controlled by another user. It also does not create files atomically with exclusive-create semantics. Consequently, execution in a shared or attacker-writable directory creates a time-of-check/time-of-use and symlink-following risk.
Replacing slash and backslash characters limits direct directory traversal through the DOI, but it does not prevent an attacker from predicting the resulting filename and creating that path before execution.
Attack Path
- The victim invokes the script with an output directory writable by an attacker, such as a shared workspace.
- The attacker predicts the fixed
temp_scihub.htmlpath or derives the final PDF filename from the DOI. - The attacker creates a symbolic link at ...[truncated 956 chars]
- Remediation
View remediation
Remediation Suggestions
- Create temporary files with Python's
tempfile.NamedTemporaryFileortempfile.mkstempin a private directory with restrictive permissions. - Do not use a fixed temporary filename inside a potentially shared output directory.
- Reject existing symbolic links and non-regular destination files.
- Create final output files using exclusive-create semantics, such as
os.openwithO_CREAT | O_EXCL | O_NOFOLLOWwhere supported. - Download into a secure temporary file, validate the content, and use an atomic rename to publish the final PDF.
- Define an explicit overwrite policy. Require user confirmation or fail safely if the final filename already exists.
- Ensure output directories are owned by the executing user and are not writable by untrusted accounts.
- Use
try/finallycleanup so securely created temporary files are removed on every error path.
- Create temporary files with Python's
