This release includes 1 security fix for security teams reviewing exposed deployments.
Topics
+11 more
Affected surfaces
Summary
AI summaryFixes a path traversal vulnerability in dataset archive extraction.
Full changelog
Security fix
This release fixes a path traversal in dataset archive extraction (ludwig/datasets/archives.py). Anyone who extracts tar archives from sources they do not fully control should upgrade.
What was wrong
extract_archive() validated that every tar member name resolved inside the destination directory, then called extractall(). That validation did not inspect link members, so it could be bypassed.
An archive containing a symlink pointing outside the destination, followed by a regular file whose name resolves through that symlink, passed validation: at check time the symlink does not exist yet, and both member names look like they land inside the destination. extractall() then created the link and wrote through it, placing archive-controlled content at an arbitrary path with the privileges of the extracting process.
A second, separate issue in the same containment check: it used os.path.commonprefix, which compares characters rather than path components, so a destination of /data/dest also accepted /data/dest-evil as being inside it.
Affected on Python 3.12 and 3.13, which is the range Ludwig supports. Python 3.14 was not affected, because TarFile.extractall() there already defaults to filter="data".
What changed
- Link targets are now validated in addition to member names, for both symlinks and hard links
extractall()is called withfilter="data", which independently refuses escaping links on 3.12 and 3.13- The containment check uses
os.path.commonpathinstead ofos.path.commonprefix - Extraction failures now raise a typed
UnsafeArchiveErrorrather than a bareException - Added regression tests covering symlink, hard link, absolute path, parent traversal, and sibling directory escapes
Credit
Reported by Udit Jain, who found the issue, verified it against the shipped code, and offered coordinated disclosure. Thank you.
Private Vulnerability Reporting is now enabled on this repository, and there is a SECURITY.md describing how to report future issues.
Full changelog: https://github.com/ludwig-ai/ludwig/compare/v0.17.7...v0.17.8
Security Fixes
- CVE-2025-XXXXX — Path traversal in `ludwig/datasets/archives.py` allowing arbitrary file writes via symlink and hard link members; fixed by validating link targets, using `filter="data"` with `TarFile.extractall()`, switching to `os.path.commonpath`, and raising `UnsafeArchiveError`.
Weekly OSS security release digest.
The CVE patches and breaking changes that affected production tools this week. One email, every Sunday.
No spam, unsubscribe anytime.
Share this release
About ludwig
Low-code framework for building custom LLMs, neural networks, and other AI models
Related context
Related tools
Beta — feedback welcome: [email protected]