binary-husky/gpt_academic · warning · Exception
Attempted Path Traversal in {member.name}
Error message
Attempted Path Traversal in {member.name} What it means
Companion check to error 198: for each tar member, member.name is normalized, joined with dest_dir, made absolute, and required to stay inside dest_dir + os.sep; otherwise extraction aborts with Exception('Attempted Path Traversal in {member.name}'). This stops '../'-style members from writing outside the extraction directory (zip-slip).
Source
Thrown at shared_utils/handle_upload.py:143
# Extract the archive based on its extension
if file_extension == ".zip":
with zipfile.ZipFile(file_path, "r") as zipobj:
zipobj._extract_member = lambda a,b,c: zip_extract_member_new(zipobj, a,b,c) # 修复中文乱码的问题
zipobj.extractall(path=dest_dir)
logger.info("Successfully extracted zip archive to {}".format(dest_dir))
elif file_extension in [".tar", ".gz", ".bz2"]:
try:
with tarfile.open(file_path, "r:*") as tarobj:
# 清理提取路径,移除任何不安全的元素
for member in tarobj.getmembers():
member_path = os.path.normpath(member.name)
full_path = os.path.join(dest_dir, member_path)
full_path = os.path.abspath(full_path)
if member.islnk() or member.issym():
raise Exception(f"Attempted Symlink in {member.name}")
if not full_path.startswith(os.path.abspath(dest_dir) + os.sep):
raise Exception(f"Attempted Path Traversal in {member.name}")
tarobj.extractall(path=dest_dir)
logger.info("Successfully extracted tar archive to {}".format(dest_dir))
except tarfile.ReadError as e:
if file_extension == ".gz":
# 一些特别奇葩的项目,是一个gz文件,里面不是tar,只有一个tex文件
import gzip
with gzip.open(file_path, 'rb') as f_in:
with open(os.path.join(dest_dir, 'main.tex'), 'wb') as f_out:
f_out.write(f_in.read())
else:
raise e
# 第三方库,需要预先pip install rarfile
# 此外,Windows上还需要安装winrar软件,配置其Path环境变量,如"C:\Program Files\WinRAR"才可以
elif file_extension == ".rar":
try:
import rarfile # 用来检查rarfile是否安装,不要删除View on GitHub (pinned to d6bde0fa54)
Solutions
- Do not upload the archive; inspect it ('tar -tvf') and remove/rewrite entries with '..' or leading '/' components.
- Repack cleanly from a fresh directory (tar -czf from inside the source dir avoids absolute prefixes).
- Treat repeated occurrences as a sign of a hostile file — do not whitelist.
Example fix
# shell: inspect and repack safely # tar -tvf upload.tar # look for ../ or leading / # mkdir clean && tar -xzf upload.tar -C clean # only after manual review # (cd clean && tar -czf clean.tar.gz .)
Defensive patterns
Strategy: validation
Validate before calling
import tarfile, os
def tar_members_escape(dest_dir: str, path: str) -> list:
root = os.path.abspath(dest_dir) + os.sep
with tarfile.open(path, 'r:*') as t:
return [m.name for m in t.getmembers()
if not (os.path.abspath(os.path.join(dest_dir, os.path.normpath(m.name))).startswith(root))]
if tar_members_escape(dest_dir, upload_path):
reject_upload('archive contains path traversal entries') Try / catch
try:
extract_archive(upload_path, dest_dir)
except Exception as e:
if 'Attempted Path Traversal' in str(e):
quarantine_upload(upload_path) # suspicious file — flag it
else:
raise Prevention
- Inspect archives with tar -tvf and reject entries containing '..' or leading '/'.
- Create archives from inside the source directory to avoid absolute prefixes.
- Quarantine, never whitelist, archives that trip this guard.
When it happens
Trigger: Uploading a tar archive containing member names like '../../etc/cron.d/x' or absolute paths that, after normpath/abspath, resolve outside the destination upload directory.
Common situations: Malicious crafted archives targeting the upload handler; rarely, archives built with unusual tooling that emits './'-prefixed or absolute entry names that normalize outside dest_dir; the guard is intentional and should not fire for normal archives.
Related errors
- Attempted Symlink in {member.name}
- 输入文件的路径 ({path_or_url}) 存在,但位置非法。请将文件上传后再执行该任务。
- 输入文件的路径 ({path_or_url}) 存在,但属于其他用户。请将文件上传后再执行该任务。
AI-assisted analysis of binary-husky/gpt_academic@d6bde0fa54 (2026-08-14).
Data as JSON: /api/errors/092359b37ee68e39.
Report an issue: GitHub.