T09 · Insecure Skill Coding Practices
- Location
SKILL.md:48- Finding
Predictable Temporary Files Permit Symlink Attacks and Data Exposure
- Content
View full analysis
Vulnerability Details
File Location:
SKILL.md, lines 48-59
Vulnerability Type: Predictable and insecure temporary-file handling
Risk Level: MediumVulnerable Code:
python for i, page in enumerate(doc): # Render page to a high-resolution image bitmap = page.render(scale=2) tmp_img = f"/tmp/page_{i}.png" bitmap.to_pil().save(tmp_img) # Run OCR (assuming English and Simplified Chinese packs are installed) text = pytesseract.image_to_string(Image.open(tmp_img), lang='chi_sim+eng') full_text.append(text) # Cleanup temporary file os.remove(tmp_img)Technical Analysis
The example uses fixed temporary paths such as
/tmp/page_0.png. These names are predictable and shared by every invocation of the skill. A concurrent process can create or manipulate the expected path before the image is saved.On systems with a shared
/tmpdirectory, an attacker may pre-create the expected path as a symbolic link. The image-saving operation can follow that link and overwrite the linked destination if the invoking process has sufficient permission. Concurrent OCR executions can also overwrite or delete one another's files, leading to integrity failures and possible cross-user document disclosure.Cleanup is not protected by a
finallyblock. If PDF rendering, image saving, image loading, or OCR raises an exception, the temporary image remains on disk and may contain sensitive document content.Attack Path
- The attacker determines that the first rendered page will use
/tmp/page_0.png. - Before the victim starts extraction, the attacker creates that path as a symbolic link to a file writable by the victim process.
- The victim runs the documented extraction script on a PDF.
bitmap.to_pil().save(tmp_img)opens the predictable path and may follow the symbolic link.- The linked file is overwritten with rendered PDF image data under ...[truncated 821 chars]
- The attacker determines that the first rendered page will use
- Remediation
View remediation
Remediation Suggestions
- Avoid writing page images to disk when possible. Pass the in-memory PIL image directly to
pytesseract.image_to_string. - If disk-backed files are required, create a private randomized directory using
tempfile.TemporaryDirectory(). - Create temporary files atomically with restrictive permissions through
tempfile.NamedTemporaryFilerather than constructing filenames manually. - Place cleanup in a
finallyblock or use context managers so files are removed when rendering or OCR fails. - Ensure temporary directories and files are accessible only to the invoking user.
- Do not reuse temporary paths across pages, documents, users, or concurrent executions.
A safer in-memory approach is:
python for page in doc: bitmap = page.render(scale=2) image = bitmap.to_pil() text = pytesseract.image_to_string(image, lang="chi_sim+eng") full_text.append(text)- Avoid writing page images to disk when possible. Pass the in-memory PIL image directly to
