CVE-2026-13214 Overview
CVE-2026-13214 is a stack buffer overflow in the Open Charge Point Protocol (OCPP) 1.6 client shipped with the Zephyr real-time operating system. The vulnerability resides in parse_getconfig_msg() inside subsys/net/lib/ocpp/ocpp_j.c. When the charge point receives a GetConfiguration request from its central system, the handler copies the attacker-controlled JSON key string into a fixed 50-byte stack buffer using an unbounded strcpy(). The message length is bounded only by CONFIG_OCPP_RECV_BUFFER_SIZE (default 2048 bytes), allowing a substantial overflow. The flaw is tracked as an out-of-bounds write [CWE-787].
Critical Impact
A malicious or compromised central system, or a network attacker on an unencrypted WebSocket link, can smash the OCPP reader thread's stack remotely, causing denial of service and potentially remote code execution on the charge point.
Affected Products
- Zephyr RTOS builds that enable the OCPP 1.6 client subsystem (subsys/net/lib/ocpp)
- Charge point firmware based on Zephyr's OCPP 1.6 client prior to commit afbf880b04188ae53451a0ade4ac62b654fdff34
- Devices connecting to a central system over the OCPP WebSocket transport
Discovery Timeline
- 2026-08-25 - CVE-2026-13214 published to NVD
- 2026-08-26 - Last updated in NVD database
Technical Details for CVE-2026-13214
Vulnerability Analysis
The OCPP 1.6 client parses JSON messages received from the central system inside the reader thread ocpp_wsreader(). Incoming payloads land in ui->recv_buf, then a Protocol Data Unit (PDU) function table dispatches each request to a dedicated handler. For GetConfiguration, that handler is parse_getconfig_msg().
The caller declares a fixed stack buffer skey[CISTR50] (50 bytes) in subsys/net/lib/ocpp/ocpp.c and passes it to parse_getconfig_msg(). The handler then invokes strcpy(key, payload.key[0]) without validating length. Because payload.key[0] points directly into the receive buffer, any JSON key value longer than 49 bytes overwrites adjacent stack data on the reader thread.
Sibling handlers in the same file already used bounded copies, which made the unbounded strcpy() an isolated regression. The corrupted stack frame can overwrite saved registers, return addresses, or thread control structures, producing a crash at minimum and potentially arbitrary code execution when stack canaries and Memory Protection Unit (MPU) enforcement are absent.
Root Cause
The root cause is missing bounds checking on attacker-controlled input. strcpy() copies until it encounters a NUL terminator, and the JSON parser does not enforce the OCPP CiString50Type length constraint before handing the pointer to the handler.
Attack Vector
An attacker who controls the configured central system endpoint sends a crafted GetConfiguration request with a key field longer than 50 bytes. A network-adjacent attacker performing a man-in-the-middle attack against an unencrypted (ws:// rather than wss://) OCPP session can also inject the message. No authentication or user interaction is required on the charge point side once the WebSocket session is established.
// Security patch in subsys/net/lib/ocpp/ocpp_j.c
// net: ocpp: bound GetConfiguration key copy
/* key is optional so return success*/
if (payload.key[0] != NULL) {
- strcpy(key, payload.key[0]);
+ strncpy(key, payload.key[0], CISTR50 - 1);
+ key[CISTR50 - 1] = '\0';
}
return 0;
// Source: https://github.com/zephyrproject-rtos/zephyr/commit/afbf880b04188ae53451a0ade4ac62b654fdff34
The fix replaces the unbounded strcpy() with strncpy() capped at CISTR50 - 1 and explicitly NUL-terminates the buffer, matching the pattern used by neighboring handlers.
Detection Methods for CVE-2026-13214
Indicators of Compromise
- OCPP GetConfiguration requests containing a key value longer than 50 bytes on the wire.
- Unexpected reboots, watchdog resets, or stack-canary faults on charge point devices shortly after a central system message.
- WebSocket sessions to charge points originating from unexpected IP addresses or unauthenticated central system endpoints.
Detection Strategies
- Inspect OCPP JSON-RPC traffic at the network boundary and flag GetConfiguration messages whose key array elements exceed the CiString50Type limit.
- Correlate charge point crash logs and thread fault dumps with recent central system message activity.
- Enforce mutual TLS on the OCPP WebSocket transport so that only authenticated central systems can reach the vulnerable handler.
Monitoring Recommendations
- Log every OCPP session establishment, including source address, TLS status, and negotiated cipher suite.
- Alert on repeated malformed OCPP frames or oversized JSON fields from a single peer.
- Capture core dumps and MPU fault records from Zephyr devices and forward them to a centralized log store for offline analysis.
How to Mitigate CVE-2026-13214
Immediate Actions Required
- Update Zephyr source trees to include commit afbf880b04188ae53451a0ade4ac62b654fdff34 and rebuild charge point firmware.
- Restrict OCPP WebSocket exposure so charge points only accept connections from a known, authenticated central system.
- Enable stack canaries (CONFIG_STACK_CANARIES) and MPU-based stack guards (CONFIG_HW_STACK_PROTECTION, CONFIG_MPU_STACK_GUARD) in Zephyr builds to raise the bar for exploitation.
Patch Information
The upstream fix is available in the Zephyr project. See the GitHub Commit Update and the GitHub Security Advisory GHSA-fqhf-6v24-4px2. Vendors integrating Zephyr's OCPP subsystem should backport the patch or upgrade to a release containing it before redeploying charge point firmware.
Workarounds
- Deploy OCPP exclusively over wss:// with certificate validation to prevent man-in-the-middle injection of malicious frames.
- Place a protocol-aware proxy in front of charge points that rejects GetConfiguration messages with key values exceeding 50 bytes.
- Segment charge point management networks and block inbound WebSocket traffic from untrusted origins at the firewall.
# Example Zephyr Kconfig hardening for OCPP charge points
CONFIG_STACK_CANARIES=y
CONFIG_HW_STACK_PROTECTION=y
CONFIG_MPU_STACK_GUARD=y
CONFIG_OCPP_RECV_BUFFER_SIZE=2048
CONFIG_NET_SOCKETS_TLS=y
CONFIG_MBEDTLS_TLS_VERSION_1_2=y
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

