T09 · Insecure Skill Coding Practices
- Location
run.py:145- Finding
Unsafe Archive Extraction Permits File Overwrite Through Link Entries
- Content
View full analysis
Vulnerability Details
File Location:
run.py:145-150
Vulnerability Type: Unsafe archive extraction
Risk Level: HighVulnerable Code:
python # Extract bio = io.BytesIO(blob) with tarfile.open(fileobj=bio, mode="r:gz") as tar: # Security check for Zip Slip for member in tar.getmembers(): if os.path.isabs(member.name) or ".." in member.name: raise Exception(f"Security Error: Archive contains unsafe path {member.name}") tar.extractall(path=".") # Extract to current dir, overwritingTechnical Analysis
The restore operation treats a database-supplied archive as trusted after checking only the textual names of its members. The check does not reject symbolic links, hard links, device nodes, or other special archive entries. It also does not validate link targets or resolve final destination paths before extraction.
An archive can contain a link entry whose member name appears safe but whose target refers outside the current directory. Subsequent entries may then write through that link. The call to
extractall()also deliberately overwrites existing files in the current working directory.Because the archive is retrieved using a user-supplied DSN, an attacker who controls that database—or who acquires credentials for the legitimate transfer database—can supply a crafted archive.
Attack Path
- The attacker creates or compromises a MySQL-compatible database accessible to the victim.
- The attacker creates a
teleporttable containing a malicious gzip-compressed tar archive underid=1. - The archive includes a symbolic or hard link with a benign member name but an unsafe target, followed by a file written through that link.
- The attacker gives the victim the malicious DSN, or replaces the archive in a legitimate transfer database.
- The victim runs
run.py --action restore --dsn .... - The member-name checks pass because the unsafe destina ...[truncated 793 chars]
- Remediation
View remediation
Remediation Suggestions
- Extract into a newly created, permission-restricted staging directory rather than directly into the current workspace.
- Permit only regular files and directories. Reject symbolic links, hard links, device nodes, FIFOs, and other special member types.
- Resolve each proposed destination with
pathlib.Path.resolve()and verify that it remains beneath the resolved staging-directory root. - Validate both member names and link targets.
- Use a safe extraction filter supported by the deployed Python version, while retaining explicit validation for compatibility.
- Present a manifest and require confirmation before replacing existing workspace files.
- Copy validated files from staging into the destination using controlled overwrite rules rather than calling unrestricted
extractall(). - Run restoration with the least-privileged account required for the workspace.
