
Dokumentiert CVE-2026-65320, einen Tar-Slip-Pfad-Traversal in fastcore's untar_dir(), mit einem harmlosen Proof-of-Concept, der beliebiges Schreiben von Dateien und Codeausführung demonstriert.
untar_dir()Schweregrad: Kritisch, CVSS 3.1 9.8
Vektor (v3.1): CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Betroffen: fastcore <= 2.2.30
Behoben in: Zum Zeitpunkt der Erstellung nicht behoben
CWE: CWE-22 (Improper Limitation of a Pathname to a Restricted Directory, 'Path Traversal')
Komponente: fastcore.xtras.untar_dir() → fastcore.xtras._unpack() → shutil.unpack_archive()
Hochrisiko-Laufzeitumgebung: Python < 3.14 (Python 3.14 macht den sicheren data-Tar-Filter zum Standard)
Gemeldet von: Rahul Karne
CNA: VulnCheck
fastcore.xtras.untar_dir(fname, dest) ist ein dokumentierter Helfer, der ein Archiv „nach dest" entpackt.
Intern übergibt er das Archiv an shutil.unpack_archive() der Standardbibliothek ohne Extraktionsfilter, ohne Validierung der Pfade der Archivelemente und ohne jegliche Containment-Prüfung nach der Extraktion.
Infolgedessen kann ein TAR-Archiv, dessen Elemente ../-Traversierungssequenzen oder absolute Pfade enthalten, Dateien außerhalb des Verzeichnisses schreiben, in das der Aufrufer fastcore angewiesen hat zu extrahieren.
Ein Aufrufer, der vernünftigerweise erwartet, dass untar_dir(fname, dest) alles auf dest beschränkt, erhält stattdessen beliebiges Dateischreiben überall dort, wo der Prozess schreiben kann.
Beliebiges Dateischreiben unter der Berechtigung des Prozesses, der untar_dir() aufruft.
Je nachdem, was überschrieben wird, kann dies zu Folgendem führen:
Der Proof of Concept demonstriert die vollständige Kette Schreiben → Import → Codeausführung von Anfang bis Ende, vollständig innerhalb eines harmlosen Demo-Verzeichnisses.
fastcore ist eine grundlegende Abhängigkeit im gesamten fast.ai-Ökosystem, einschließlich:
fastainbdevghapiEs wird zig Millionen Mal pro Monat heruntergeladen.
untar_dir() ist das Extraktionsprimitiv hinter dem üblichen Workflow „ein Archiv herunterladen, dann entpacken", der demselben allgemeinen Muster wie fastais untar_data folgt.
Jeder Codepfad, der untar_dir() ein Archiv zuführt, dessen Inhalt nicht vollständig vertrauenswürdig ist, ist exponiert.
Der verwundbare Code befindet sich in fastcore/xtras.py:
def _unpack(fname, out):
import shutil
shutil.unpack_archive(str(fname), str(out)) # <-- no filter, no validation
ls = out.ls()
return ls[0] if len(ls) == 1 else out
def untar_dir(fname, dest, rename=False, overwrite=False, uid=-1, gid=-1):
"untar `file` into `dest` ..."
import tempfile, shutil
dest = Path(dest)
with tempfile.TemporaryDirectory() as d:
out = Path(d) / remove_suffix(Path(fname).stem, '.tar')
out.mkdir()
...
src = _unpack(fname, out) # extraction escapes `out` here
...
shutil.move(str(src), dest)
...
return dest
untar_dir() erstellt ein internes temporäres Extraktionsverzeichnis:
<tempdir>/<random>/<archive-stem>/
Anschließend ruft es _unpack() auf, das das Archiv direkt weiterleitet an:
shutil.unpack_archive()
Bei TAR-Archiven ruft dies letztlich tarfile.extractall() auf.
Unter Python < 3.14 ist das Standard-Extraktionsverhalten fully_trusted, was bedeutet, dass Traversierungselemente berücksichtigt werden können.
Beispielsweise wird ein Archivelement wie:
../../../some/other/dir/file
relativ zum Extraktionsverzeichnis geschrieben und kann dieses daher verlassen.
Nichts in fastcore:
filter="data", wo unterstützt...-Pfadkomponenten ab.untar_dir() behandelt shutil.unpack_archive() so, als wäre es ein sicherer, sandboxed Archiv-Extraktor.
Das ist es nicht.
Die Dokumentation der Python-Standardbibliothek warnt davor, dass das Extrahieren nicht vertrauenswürdiger Archive Dateien außerhalb des angeforderten Ziels erstellen kann, und empfiehlt eine sichere Extraktionsfilterung für TAR-Archive.
fastcore übergibt weder einen geeigneten Extraktionsfilter noch implementiert es eine äquivalente Containment-Absicherung für die unterstützten Python-Versionen.
Es warnt Aufrufer von untar_dir() auch nicht vor diesem sicherheitsrelevanten Verhalten.
TAR-Elemente können beliebige Pfadzeichenketten enthalten.
Unter betroffenen Python-Versionen neutralisiert tarfile.extractall() standardmäßig nicht automatisch ..-Traversierungssequenzen.
Das Schreiben eines Traversierungselements relativ zum temporären Extraktionsverzeichnis von fastcore reicht daher aus, um dieses Verzeichnis zu verlassen und überall dorthin zu schreiben, wo der Prozess Schreibberechtigung hat.
Ein zuverlässiges Primitiv ist die relative Traversierung wie:
../../../target/file
Dies ist die Technik, die im Proof of Concept verwendet wird.
Die gefährliche Eingabe sind die Archivinhalte, nicht der vom Entwickler gewählte Zielpfad.
Archive werden häufig von externen oder halbvertrauenswürdigen Orten bezogen, einschließlich:
Jeder Dienst oder jedes Tool, das ein Archiv aus einer nicht vertrauenswürdigen oder halbvertrauenswürdigen Quelle herunterlädt und anschließend mit untar_dir() verarbeitet, kann daher erreichbar sein.
Der PoC enthält außerdem eine Variante, die das präparierte Archiv von einem angreiferkontrollierten HTTP-Endpunkt bereitstellt, um diesen Bereitstellungspfad zu demonstrieren.
Eine erfolgreiche Ausbeutung erfordert:
Die Anwendung ruft fastcore.xtras.untar_dir() mit einem Archiv auf, dessen Inhalt vom Angreifer beeinflusst wird, wie etwa ein hochgeladenes, heruntergeladenes oder anderweitig nicht vertrauenswürdiges Archiv.
Die Laufzeitumgebung verwendet Python < 3.14 oder eine andere Konfiguration, in der ein sicherer TAR-Extraktionsfilter nicht erzwungen wird.
Für die Eskalation vom beliebigen Dateischreiben zur Codeausführung importiert oder lädt der Prozess später eine Datei von einem durch die Traversierung erreichbaren Ort, wie etwa:
Beliebiges Dateischreiben und Konfigurations-/Datenänderung erfordern nur die Bedingungen 1 und 2.
poc_fastcore_cna_demo.py ruft die echte fastcore.xtras.untar_dir()-API auf.
Die Demonstration ist absichtlich harmlos.
Jede vom PoC erstellte Datei bleibt innerhalb eines einzigen Demo-Verzeichnisses, das über Folgendes angegeben wird:
--demo-root
Der PoC ändert keine echten Systemdateien und greift nicht auf Cloud-Dienste oder Anmeldeinformationen zu.
_unpack() und untar_dir() aus.