Skip to content

ludwig

v0.17.8 Security

This release includes 1 security fix for security teams reviewing exposed deployments.

Published 6h LLM Frameworks
✓ No known CVEs patched
Read the diff → Tool health → What is this tool? →
This release patches 1 known CVE

Topics

computer-vision data-centric data-science deep machine-learning deeplearning
+11 more
fine-tuning learning llama llama2 llm llm-training machinelearning mistral natural-language natural-language-processing pytorch

Affected surfaces

rce_ssrf

Summary

AI summary

Fixes 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 with filter="data", which independently refuses escaping links on 3.12 and 3.13
  • The containment check uses os.path.commonpath instead of os.path.commonprefix
  • Extraction failures now raise a typed UnsafeArchiveError rather than a bare Exception
  • 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

Track ludwig

Get notified when new releases ship.

Sign up free

About ludwig

Low-code framework for building custom LLMs, neural networks, and other AI models

All releases →

Beta — feedback welcome: [email protected]