T09 · Insecure Skill Coding Practices
- Location
scripts/download_data.py:62- Finding
Unsafe Extraction of an Untrusted Tar Archive
- Content
View full analysis
Vulnerability Details
File Location:
scripts/download_data.py, lines 62-71
Vulnerability Type: Path traversal and arbitrary file overwrite through unsafe archive extraction
Risk Level: HighVulnerable Code
python def extract_tar(tar_path: str, output_dir: str) -> bool: """解压 tar.gz 文件""" try: logger.info(f"正在解压: {tar_path}") with tarfile.open(tar_path, 'r:gz') as tar: tar.extractall(path=output_dir) logger.info(f"解压完成: {output_dir}") return True except Exception as e: logger.error(f"解压失败: {e}") return FalseTechnical Analysis
tar.extractall()is invoked on a remotely downloaded archive without validating archive member names or link targets. Depending on the Python runtime and extraction behavior, malicious entries containing absolute paths,../traversal components, symbolic links, hard links, or special files may escape the intended extraction directory.The archive comes from an external GitHub release and is not authenticated independently. Consequently, compromise of the upstream repository, its release publishing credentials, or the release asset could expose users to a crafted archive.
Attack Path
- An attacker gains control over, or otherwise compromises, the upstream release asset.
- The attacker creates
qlib_bin.tar.gzwith a member such as../../.bashrc, or with a link that redirects a later archive member outside the destination. - A user runs
python scripts/download_data.py --latestor invokesInvestmentData.update_data(). - The Skill downloads the malicious archive into the data directory.
tar.extractall(path=output_dir)processes the malicious member without application-level validation.- Files outside
output_dirmay be created or overwritten with the privileges of the user running the Skill. - If a startup file, imported Python module, executable, or security-sensitive configuration is overwritten, attacker- ...[truncated 761 chars]
- Remediation
View remediation
Remediation Suggestions
-
Validate every archive member before extraction:
- Reject absolute paths.
- Reject paths containing traversal components.
- Resolve the destination and verify it remains beneath the resolved extraction root.
- Reject device files and other special entries.
- Reject symbolic and hard links, or validate their resolved targets rigorously.
-
On supported Python versions, use the restrictive data extraction filter:
python with tarfile.open(tar_path, "r:gz") as tar: tar.extractall(path=output_dir, filter="data")-
Do not rely exclusively on the runtime filter. Add explicit containment checks for compatibility and defense in depth.
-
Extract into a newly created temporary directory rather than directly into the live data directory. Move validated files into place only after successful verification.
-
Verify the archive's checksum or signature before opening it.
-
Run the downloader with a dedicated, least-privileged account and never as an administrator or root user.
-
