
Sicherheitshinweis: CVE-2026-38361 mehrere DoS-Schwachstellen (CWE-400/CWE-670) in dash-uploader (Python/PyPI)
Mehrere nicht authentifizierte Denial-of-Service-Probleme (DoS) in fohrloop/dash-uploader (Python, PyPI), einschließlich (aber nicht beschränkt auf) Absturz des Prozesses durch Speichererschöpfung (Out-of-Memory, OOM), Kürzung von Dateien auf null Byte, dauerhafte Erschöpfung des Speicherplatzes und vollständige Umgehung des dokumentierten max_file_size-Limits. Über denselben nicht bereinigten Parametersatz sind weitere Wege des Ressourcenmissbrauchs möglich.
Das Repository wurde am 2025-07-19 archiviert und hat keinen aktiven Betreuer. Jede veröffentlichte Version (0.1.0 bis 0.7.0a2) ist betroffen und wird es auch bleiben. Das Paket verzeichnet weiterhin etwa 28.000 Downloads pro Monat.
Wer dash-uploader in der Produktion einsetzt, muss selbst eine Abhilfemaßnahme umsetzen. Die empfohlene Lösung ist die Migration auf die in Plotly Dash integrierte dcc.Upload-Komponente. Vollständige Optionen finden Sie unter Mitigation.
Der HTTP-Handler von dash-uploader akzeptiert nicht authentifizierte POST-Anfragen mit angreiferkontrollierten Parametern, die ohne Begrenzungsprüfungen, Ratenlimits und Bereinigungsmechanismen in Speicherzuweisung, Dateioperationen und Verzeichniserstellung einfließen. Vier unabhängige Probleme im selben Codepfad:
Verifiziert auf einem System mit 7,7 GB Arbeitsspeicher: 5 gleichzeitige POST-Anfragen mit resumableTotalChunks=30000000 lösten innerhalb von 2 Sekunden den Linux-OOM-Killer aus. Das Kernel-Log bestätigt:
Out of memory: Killed process 24203 (python3) total-vm:8302276kB, anon-rss:7068012kB
Jede Anfrage weist über eine Listenkomprehension über range(1, resumableTotalChunks + 1) etwa 2,9 GB zu. Der Serverprozess wird beendet, und die Anwendung bleibt bis zu einem manuellen Neustart vollständig unverfügbar.
Eine Datei mit 42 Byte Daten wurde durch eine einzige POST-Anfrage mit resumableTotalChunks=0 auf 0 Byte reduziert. Die Ursache ist Pythons all(), das für leere Iterablen True zurückgibt und den Upload-Handler dazu verleitet, null Chunks als abgeschlossenen Upload zu behandeln. Die vorhandene Datei wird per os.unlink() gelöscht und durch eine leere Datei ersetzt.
Es wurden 10 verwaiste temporäre Verzeichnisse mit Chunk-Dateien erstellt, die dauerhaft auf der Festplatte verbleiben. Eine codebasisweite Suche in allen Quelldateien nach cleanup, ttl, expire, garbage, purge, cron, schedule und periodic ergab null Ergebnisse. Der einzige Bereinigungsaufruf (shutil.rmtree) wird ausschließlich bei abgeschlossenen Uploads ausgeführt. Es gibt keinen Mechanismus, um Speicherplatz von unvollständigen Sitzungen zurückzugewinnen.
max_file_size (verifiziert)Der Server akzeptierte einen 5-MB-Chunk für eine Datei, die resumableTotalSize=999999999999 (~999 GB) angab, mit HTTP 200. Der Parameter max_file_size wird nur an die React-JavaScript-Komponente übergeben. Der Server prüft weder Dateigröße noch Chunk-Größe, Content-Length oder Flask MAX_CONTENT_LENGTH. Ein Entwickler, der max_file_size=10 setzt, hat keinen serverseitigen Schutz.
# dash_uploader/httprequesthandler.py
def _post(self):
resumableTotalChunks = request.form.get("resumableTotalChunks", type=int) # attacker-controlled, no bounds
...
chunk_paths = [
os.path.join(temp_dir, get_chunk_name(resumableFilename, x))
for x in range(1, resumableTotalChunks + 1) # unbounded; e.g. 30M -> ~2.9 GB -> OOM
]
upload_complete = all([os.path.exists(p) for p in chunk_paths]) # all([]) is True -> truncation when chunks=0
if upload_complete:
target_file_name = os.path.join(temp_root, resumableFilename)
if os.path.exists(target_file_name):
os.unlink(target_file_name) # existing file deleted
with open(target_file_name, "ab") as target_file:
for p in chunk_paths: # empty list -> empty file written
...
Derselbe Codepfad erzeugt sowohl den OOM-Absturz (großes resumableTotalChunks) als auch die Dateikürzungs-Primitive (resumableTotalChunks=0).
Ein Angreifer sendet nicht authentifizierte POST-Anfragen an den Endpunkt /API/resumable.
resumableTotalChunks=30000000 weisen jeweils ~2,9 GB zu und lösen den OOM-Killer aus.resumableTotalChunks=0 senden; Python all([])=True verleitet den Server dazu, die Zieldatei mit leerem Inhalt zu überschreiben.Es sind keine Authentifizierung oder Berechtigungen erforderlich.
resumableTotalChunks)os.makedirs() und nicht bereinigtem resumableIdentifierall(), das bei leeren Iterablen True zurückgibt, wenn resumableTotalChunks=0max_file_size nur im clientseitigen JavaScript durchgesetzt wird, während der serverseitige Handler keinerlei Größenvalidierung durchführt und Flask MAX_CONTENT_LENGTH niemals setztdash_uploader/httprequesthandler.py (BaseHttpRequestHandler._post-Methode)dash_uploader/upload.py (Upload-Funktion, Parameter max_file_size)dash_uploader/configure_upload.py (fehlendes MAX_CONTENT_LENGTH)Optionen für derzeitige Installationen, in der Reihenfolge der Präferenz:
dcc.Upload, der offiziellen Upload-Komponente, die mit Plotly Dash ausgeliefert wird. Sie besitzt keinen Chunk-Anzahl-Parameter, keinen temporären Zustand auf der Festplatte und respektiert Flask MAX_CONTENT_LENGTH. Keines der vier hier genannten Probleme trifft zu. Am besten geeignet für kleine und mittlere Dateien. Für sehr große Uploads siehe Punkt 2.MAX_CONTENT_LENGTH), Beschränkung der vom Client gelieferten Chunk-Anzahl und einer Allowlist für akzeptierte Dateinamen.MAX_CONTENT_LENGTH auf Anwendungsebene (die Bibliothek tut dies nicht) und lehnen Sie Eingaben auf Anwendungs- oder Reverse-Proxy-Ebene ab, sofern einer der folgenden Punkte zutrifft:
resumableTotalChunks <= 0resumableTotalChunks eine angemessene Obergrenze überschreitet (z. B. 10.000)resumableTotalSize das vom Entwickler konfigurierte max_file_size überschreitet0.6.1 (stabile Linie). Vorabversionen reichen bis 0.7.0a2.dash. Optionale Abhängigkeit: pyyaml. Lizenz: MIT.Muhammad Fitri Bin Mohd Sultan
| CVE-ID | CVE-2026-38361 (NVD) |
| Schwachstelle | Unkontrollierte Ressourcennutzung (CWE-400), Immer falsche Kontrollfluss-Implementierung (CWE-670) |
| CVSS 3.1 | 7,5 / Hoch (AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H) |
| Produkt | dash-uploader |
| Betroffene Versionen | 0.1.0 bis 0.7.0a2 (alle 18 Releases) |
| Behobene Version | keine (Projekt am 2025-07-19 archiviert) |
| Angriffsvektor | Remote, nicht authentifiziert |
| Entdecker | Muhammad Fitri Bin Mohd Sultan |
| Zugewiesen von | MITRE, 2026-05-07 |
| Verwandt | CVE-2026-38360 (Path-Traversal in derselben Bibliothek) |
| Datum | Ereignis |
|---|
| 2026-03-19 | Schwachstellen während einer Sicherheitsforschung an einer Produktionsbereitstellung entdeckt. |
| 2026-03-22 | CVE-Anfrage bei MITRE eingereicht. |
| 2026-05-07 | CVE-2026-38361 von MITRE zugewiesen. |
| 2026-05-07 | Öffentlicher Sicherheitshinweis veröffentlicht. |
| 2026-05-09 | CVE-Eintrag in der MITRE-CVE-Datenbank und der NVD veröffentlicht. |