T09 · Insecure Skill Coding Practices
- Location
scripts/document_reader.py:227- Finding
Predictable Temporary Files Allow Symlink-Based File Overwrite
- Content
View full analysis
Vulnerability Details
File Location:
scripts/document_reader.py:227-237,scripts/document_reader.py:278-288,scripts/document_reader.py:324-334, andscripts/document_reader.py:372-382
Vulnerability Type: Predictable temporary filename and unsafe file creation
Risk Level: HighVulnerable Code
The ZIP archive handler uses an archive-controlled basename to construct a predictable path:
python temp_path = f"/tmp/doc_reader_{os.path.basename(inner_path)}" with open(temp_path, 'wb') as tf: tf.write(content_bytes) try: result = self.read_document(temp_path) result['archive_path'] = zip_path result['inner_path'] = inner_path return result finally: if os.path.exists(temp_path): os.unlink(temp_path)The TAR archive handler repeats the same pattern:
python temp_path = f"/tmp/doc_reader_{os.path.basename(inner_path)}" with open(temp_path, 'wb') as tf_tmp: tf_tmp.write(content_bytes) try: result = self.read_document(temp_path) result['archive_path'] = tar_path result['inner_path'] = inner_path return result finally: if os.path.exists(temp_path): os.unlink(temp_path)The RAR archive handler also uses the same predictable path:
python temp_path = f"/tmp/doc_reader_{os.path.basename(inner_path)}" with open(temp_path, 'wb') as tf_tmp: tf_tmp.write(content_bytes) try: result = self.read_document(temp_path) result['archive_path'] = rar_path result['inner_path'] = inner_path return result finally: if os.path.exists(temp_path): os.unlink(temp_path)The 7-Zip archive handler repeats the vulnerable construction:
python temp_path = f"/tmp/doc_reader_{os.path.basename(inner_path)}" with open(temp_path, 'wb') as tf_tmp: tf_tmp.write(content_bytes) try: result = self.read_document(temp_path) result['archive_path'] ...[truncated 2382 chars]- Remediation
View remediation
Remediation Suggestions
- Replace manually constructed
/tmppaths withtempfile.NamedTemporaryFileor a privatetempfile.TemporaryDirectory. - Use random, operating-system-generated names and restrictive permissions.
- Keep the securely created file descriptor open while writing the archive member.
- Do not reopen a pathname after creation unless ownership and file type have been validated.
- Ensure the temporary object is not a symbolic link and is owned by the current process account.
- Create a separate private temporary directory for each invocation to prevent collisions between concurrent processes.
- Run document parsing under a dedicated, unprivileged account with access only to required inputs.
- Apply the correction consistently to the ZIP, TAR, RAR, and 7-Zip handlers.
- Replace manually constructed
