| Field | Details |
|---|---|
| Product | openplcproject/OpenPLC_v3 (github.com/thiagoralves/OpenPLC_v3) |
| Affected Version | All versions up to latest master (commit b4702061dc14d1024856f71b4543298d77007b88) |
| Vulnerability | Heap-Based Buffer Overflow |
| CWE | CWE-122 (Heap-based Buffer Overflow) |
| CVSS 3.1 Score | 8.8 HIGH (AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H) |
| File | webserver/core/modbus_master.cpp — line 92, 195 |
| Function | getData() called from parseConfig() |
| Component | Modbus Master — slave device config parser |
Note: This repository was archived on 2026-04-04. The vendor has confirmed this issue does not affect OpenPLC Runtime v4.
A heap-based buffer overflow (CWE-122) exists in the getData() function in webserver/core/modbus_master.cpp (line 92), called from parseConfig() at line 195. An authenticated attacker can send a crafted HTTP POST request to the /modbus endpoint with an oversized device_name field, causing a 100-byte overflow into adjacent struct fields on the heap.
getData() reads characters between two delimiter characters and writes them into a caller-supplied buffer without any size parameter or bounds check. At parseConfig() line 195, it is called with mb_devices[n].dev_name — a 100-byte heap-allocated field. Any device name longer than 99 characters causes an overflow into adjacent struct fields.
Vulnerable file: webserver/core/modbus_master.cpp, lines 92-110
HTTP POST /modbus -> mbconfig.cfg -> parseConfig() -> getData()
An attacker with access to the web interface sends a crafted POST request to /modbus with device_name = "A" x 200.
| Parameter | Value | Notes |
|---|---|---|
| dev_name buffer size | 100 bytes | MB_device.dev_name[100] — heap allocated |
| Attacker payload | 200 bytes | HTTP POST device_name = "A" x 200 |
| protocol field offset | 108 | First field overwritten |
| dev_address offset | 109 | char dev_address[100] — fully overwritten |
| ip_port offset | 210 | uint16_t ip_port — overwritten |
| Bytes past allocation | 100 bytes | 200 payload - 100 buffer = 100 bytes overflow |
[BEFORE overflow] mb_devices[0].protocol = 0xDE (canary) mb_devices[0].dev_address = "SAFE_ADDR" (canary)
[AFTER overflow] mb_devices[0].protocol = 0x41 [OVERWRITTEN: was 0xDE, got 0x41 = 'A'] mb_devices[0].dev_address = "AAAAAAAAAAAAA..." [OVERWRITTEN: was 'SAFE_ADDR']
[VULNERABLE] getData() wrote 200 bytes into dev_name[100] CWE-122: Heap-based Buffer Overflow CVSS 3.1: AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H = 8.8
- Denial of Service — Heap corruption causes PLC runtime crash. In ICS/SCADA environments this directly disrupts physical process control.
- Heap Corruption — Adjacent struct fields (protocol, dev_address, ip_port) are overwritten with attacker-controlled data.
Add bounds checking in getData():
if (j >= buf_size - 1) break;
Also add server-side length validation in sanitize_input() or the add_modbus_device route — truncate device_name to max 99 characters.
- Repository: https://github.com/thiagoralves/OpenPLC_v3
- Vulnerable file: webserver/core/modbus_master.cpp — function getData() line 92, parseConfig() line 195
- CWE-122: https://cwe.mitre.org/data/definitions/122.html
- Repository archived: 2026-04-04 — no upstream patch expected
- Tested version: master, commit b4702061dc14d1024856f71b4543298d77007b88 (latest as of 2026-06-05)
Reported by: Shuhratbek Uraimov (shuhraturaimov@gmail.com)