Tasmota fetch_jpg() strcpy() Buffer Overflow in boundary[40] (CVE-2026-38426)
by Saidakbarxon Maxsudxonov (sermikr0) · 2026-07-05
- Severity
- Critical
- CVE
- CVE-2026-38426
- Category
- network
- Affected product
- Arendst Tasmota (ESP32 firmware)
- Affected versions
- <= 15.3.0.3
- Disclosed
- 2026-07-05
- Patch status
- patched
References
Archive entry
intelseclab/poc-archiveMetadata
| Field | Value |
|---|---|
| Date Added | 2026-07-05 |
| Last Updated | 2026-05 |
| Author / Researcher | Saidakbarxon Maxsudxonov (sermikr0) |
| CVE / Advisory | CVE-2026-38426 |
| Category | network |
| Severity | Critical |
| CVSS Score | 9.8 (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H) |
| Status | PoC |
| Tags | tasmota, esp32, iot, buffer-overflow, strcpy, rce, mjpeg, scripter |
| Related | CVE-2026-38422, CVE-2026-38427 |
Affected Target
| Field | Value |
|---|---|
| Software / System | Arendst Tasmota (ESP32 firmware) |
| Versions Affected | <= 15.3.0.3 |
| Language / Platform | Python (PoC server) targeting C++/Arduino ESP32 firmware |
| Authentication Required | No (device must be scripted to connect to attacker’s MJPEG server) |
| Network Access Required | Yes |
Summary
The fetch_jpg() function’s initial-connection handling (case 0) in Tasmota’s scripter driver extracts the MJPEG multipart boundary string from the HTTP Content-Type response header and copies it into a fixed 40-byte boundary[40] field of the JPG_TASK struct using strcpy(), with no length validation. Because boundary[40] sits directly before other struct fields — including embedded WiFiClient and HTTPClient objects whose vtable pointers live further in the struct — an attacker-controlled MJPEG server can send a boundary string longer than 39 characters to overflow into and corrupt adjacent memory, potentially achieving remote code execution when a corrupted vtable pointer is later dereferenced.
Vulnerability Details
Root Cause
fetch_jpg() case 0 does strcpy(glob_script_mem.jpg_task.boundary, cp + 1) on the Content-Type boundary substring with no bounds check against the destination’s 40-byte capacity (CWE-120/CWE-787-class stack/struct overflow).
Attack Vector
- Configure a Tasmota device (via a script using
fetchjp()) to connect to an attacker-controlled MJPEG HTTP server, or MITM an existing connection. - Respond to the initial request with
Content-Type: multipart/x-mixed-replace; boundary=<50+ character string>. - Tasmota’s
strcpy()copies the oversized boundary into the fixed 40-byte buffer, overflowing into adjacentJPG_TASKstruct fields including theWiFiClient/HTTPClientobjects. - Subsequent use of the corrupted
WiFiClient/HTTPClientvtable pointers (viaread()/write()/connect()) can redirect execution.
Impact
Remote code execution or guaranteed crash on ESP32-based Tasmota devices with scripter support enabled and no authentication required.
Environment / Lab Setup
Target: ESP32 device running Tasmota <= 15.3.0.3 with a script using fetchjp()
Attacker: python3
Proof of Concept
PoC Script
See
CVE-2026-38426_poc.pyin this folder.
| |
The script serves a fake MJPEG HTTP endpoint that returns an oversized Content-Type boundary string, triggering the strcpy() overflow on a connecting Tasmota device (crash mode maximizes overflow length; info mode demonstrates targeted corruption).
Detection & Indicators of Compromise
Exception (28): epc1=... ...
Fatal exception ... rebooting
Signs of compromise:
- Device crash/reboot immediately after a
fetchjp()-initiated MJPEG connection - HTTP responses from an MJPEG source with abnormally long
boundary=values inContent-Type
Remediation
| Action | Detail |
|---|---|
| Primary fix | Update to Tasmota v15.3.0.4 or later, which bounds-checks the boundary string before copying |
| Interim mitigation | Restrict fetchjp() scripts to trusted MJPEG servers only; disable scripter support if unused |
References
Notes
Mirrored from https://github.com/sermikr0/CVE-2026-38426 on 2026-07-05.
| |