T09 · Insecure Skill Coding Practices
- Location
scripts/archive.py:25- Finding
Arbitrary File Write Through Unsafe TAR Archive Extraction
- Content
View full analysis
Vulnerability Details
File Location:
scripts/archive.py, lines 25-29
Vulnerability Type: Path traversal and unsafe link handling during TAR extraction
Risk Level: HighVulnerable Code
python def extract_tar(filepath, output_dir): """Extract tar/tar.gz/tgz file using Python stdlib""" with tarfile.open(filepath, 'r:*') as tar_ref: tar_ref.extractall(output_dir) return TrueTechnical Analysis
The application passes every TAR member directly to
tarfile.extractall()without enforcing a safe extraction filter or validating member paths and link targets.On Python versions where a restrictive extraction filter is not the default, a malicious TAR archive can contain:
- Relative traversal paths such as
../../home/user/.config/application.conf - Absolute paths targeting files outside the selected output directory
- Symbolic or hard links that redirect subsequent extraction operations outside the destination
- Special files or other unsafe TAR member types
Creating
output_dirbefore extraction does not constrain archive members to that directory. The destination of every member must be resolved and verified independently.Attack Path
-
An attacker creates a TAR, TAR.GZ, TGZ, TAR.BZ2, or TAR.XZ archive containing a member whose path traverses outside the intended extraction directory, or a link that points outside it.
-
The attacker provides the archive to a user or causes an agent to process it.
-
The user or agent runs a command such as:
bash python3 scripts/archive.py extract malicious.tar -o ./extracted -
extract_file()identifies the input as a TAR archive and callsextract_tar(). -
tar_ref.extractall(output_dir)processes the malicious member without an explicitly enforced safe filter. -
On an affected Python runtime, the crafted member is written outside
./extracted.
Impact Assessment
The attacker m ...[truncated 675 chars]
- Relative traversal paths such as
- Remediation
View remediation
Remediation Suggestions
On supported Python versions, explicitly require the safe data filter rather than relying on runtime defaults:
python def extract_tar(filepath, output_dir): destination = Path(output_dir).resolve() destination.mkdir(parents=True, exist_ok=True) with tarfile.open(filepath, "r:*") as tar_ref: tar_ref.extractall(destination, filter="data") return TrueFor compatibility with runtimes that do not support
filter="data", implement validation before extraction:- Resolve the intended destination directory to an absolute canonical path.
- Reject absolute member paths.
- Resolve each member's prospective destination and verify that it remains beneath the extraction directory.
- Reject traversal components that escape the destination.
- Reject device files, FIFOs, and other special member types.
- Reject symbolic and hard links, or separately verify that both their extraction locations and targets remain within the destination.
- Extract only after all archive members have passed validation.
- Add regression tests covering absolute paths,
../traversal, symbolic-link pivots, hard-link pivots, and special files.
