T09 · Insecure Skill Coding Practices
- Location
scripts/doc_scanner.py:442- Finding
Predictable Temporary Files Permit Symlink-Based File Overwrite
- Content
View full analysis
Vulnerability Details
File Location:
scripts/doc_scanner.py, lines 442–460
Vulnerability Type: Predictable temporary-file creation and unsafe symlink handling
Risk Level: Mediumpython for i, inp in enumerate(input_paths): temp_out = output_path.parent / f"_scan_temp_page{i+1:03d}.png" result = scan_image( inp, temp_out, mode=args.mode, dpi=args.dpi, no_warp=args.no_warp, manual_corners=getattr(args, "corners", None), ) all_results.append(result) if result["status"] == "success": temp_pages.append(temp_out) else: print(f"Error processing {inp}: {result.get('error')}", file=sys.stderr) if temp_pages: _save_as_pdf(temp_pages, output_path, args.dpi) # Clean up temp files for tp in temp_pages: tp.unlink(missing_ok=True)Technical Analysis
Multi-page processing stores intermediate images under deterministic names such as
_scan_temp_page001.pngin the user-selected output directory. The implementation does not create these files exclusively, verify that the path is not a symbolic link, or place them in a private directory with restrictive permissions.The temporary path is subsequently passed to
scan_image, which saves the processed image through Pillow. If an attacker can modify the output directory, the attacker can create a symbolic link at the predictable temporary path before processing begins. The image-writing operation can then follow that link and overwrite its target with image data.Cleanup does not prevent exploitation. Calling
unlink()afterward removes the symbolic link itself rather than restoring the overwritten target, and may make the redirection less apparent.Attack Path
- An attacker identifies a shared or attacker-writable directory that a victim will use as the PDF output directory.
- The attacker creates
_scan_temp_page001.pngin that d ...[truncated 1298 chars]
- Remediation
View remediation
Remediation Suggestions
- Create a private temporary directory using
tempfile.TemporaryDirectory()rather than storing intermediate files beside the final output. - Generate unpredictable temporary filenames using
tempfile.NamedTemporaryFile()or cryptographically random names. - Use exclusive file creation and reject paths that already exist.
- Verify that intermediate paths are regular files and not symbolic links before reading or writing them.
- Apply restrictive directory and file permissions.
- Perform cleanup in a
finallyblock so temporary data is removed on processing and PDF-generation failures. - Write the final PDF to a securely created temporary file and atomically replace the requested destination only after generation succeeds.
- Create a private temporary directory using
