CVE-2026-13217 Overview
CVE-2026-13217 is a NULL pointer dereference vulnerability in the Open Charge Point Protocol (OCPP) 1.6 client shipped with the Zephyr real-time operating system. The defect resides in ocpp_process_server_msg() within subsys/net/lib/ocpp/ocpp.c, where the code calls atoi(strtok_r(uid, "-", &tmp)) without validating the strtok_r() return value. A malicious or compromised OCPP central system, or an attacker with a man-in-the-middle position on a plaintext ws:// connection, can send a CALLRESULT message with a malformed uid field to trigger the dereference. On Zephyr targets with NULL pointer trap protection, the fault crashes the OCPP reader thread and produces a remote denial of service against the charge point.
Critical Impact
Remote attackers controlling or intercepting the OCPP server channel can crash the charge point OCPP reader thread, causing availability loss on MMU/MPU platforms or builds with CONFIG_NULL_POINTER_EXCEPTION_DETECTION.
Affected Products
- Zephyr RTOS OCPP 1.6 client (subsys/net/lib/ocpp/ocpp.c)
- Zephyr builds enabling the OCPP subsystem on MMU/MPU targets
- Zephyr builds with CONFIG_NULL_POINTER_EXCEPTION_DETECTION enabled
Discovery Timeline
- 2026-08-25 - CVE-2026-13217 published to NVD
- 2026-08-26 - Last updated in NVD database
Technical Details for CVE-2026-13217
Vulnerability Analysis
The vulnerability is a classic NULL pointer dereference [CWE-476] in the OCPP response-handling path. When parse_rpc_msg() in subsys/net/lib/ocpp/ocpp_j.c receives a JSON frame from the OCPP central system over TCP or WebSocket, it copies the server-controlled uid string into a local buffer. The response branch then splits the uid into two dash-delimited tokens to reconstruct a session handle and PDU identifier.
The first strtok_r(uid, "-", &tmp) call returns NULL when the uid is empty or contains no - delimiter. The unchecked result is passed directly to atoi(), which dereferences the NULL pointer. Because ocpp_session_is_valid() membership-validates the reconstructed session pointer before use, the impact is bounded to the NULL dereference and not arbitrary pointer manipulation.
On Zephyr targets that trap access to address zero, the fault propagates into the fatal handler and terminates the OCPP reader thread. On bare targets where address zero is readable, the call returns 0 and execution continues without effect. The impact is therefore availability-only and platform-conditional.
Root Cause
The root cause is missing return-value validation on strtok_r() before invoking atoi(). C standard library atoi(NULL) behavior is undefined, and Zephyr's optional NULL trap facility converts that undefined access into a fatal exception.
Attack Vector
An attacker requires either control of the OCPP central system the charge point connects to, or a man-in-the-middle position on a non-TLS ws:// connection. No authentication beyond the existing server session is required. The attacker responds to any CALL from the charge point with a CALLRESULT frame whose uid field is empty or omits the - delimiter.
// Zephyr patch: guard first strtok_r return before atoi()
// File: subsys/net/lib/ocpp/ocpp.c
if (is_rsp) {
buf = strtok_r(uid, "-", &tmp);
+ /* strtok_r returns NULL when no '-' is present; atoi(NULL) is UB. */
+ if (buf == NULL) {
+ return -EINVAL;
+ }
sh = (struct ocpp_session *)(uintptr_t)atoi(buf);
buf = strtok_r(NULL, "-", &tmp);
Source: Zephyr commit 4d8a9eb
// Follow-up patch: guard second strtok_r return before atoi()
// File: subsys/net/lib/ocpp/ocpp.c
sh = (struct ocpp_session *)(uintptr_t)atoi(buf);
buf = strtok_r(NULL, "-", &tmp);
+ if (buf == NULL) {
+ return -EINVAL;
+ }
pdu = atoi(buf);
if (!ocpp_session_is_valid(sh)) {
Source: Zephyr commit 3a55507
Detection Methods for CVE-2026-13217
Indicators of Compromise
- Unexpected fatal exception logs from the Zephyr OCPP reader thread referencing address 0x0 or a NULL access inside ocpp_process_server_msg().
- OCPP CALLRESULT frames observed on the wire with an empty uid field or a uid value that does not contain a - delimiter.
- Charge point reboots or WebSocket disconnects immediately following receipt of a CALLRESULT frame from the central system.
Detection Strategies
- Inspect OCPP JSON traffic between charge points and the central system for malformed uid values in CALLRESULT messages.
- Monitor Zephyr device console or remote logging channels for repeated fatal handler invocations correlated with OCPP activity.
- On plaintext ws:// deployments, deploy network sensors on the OCPP path to alert on injected or altered frames from off-path sources.
Monitoring Recommendations
- Aggregate charge point crash and reboot telemetry in a central data lake and alert on abnormal restart rates per site.
- Track TLS versus plaintext WebSocket usage across the OCPP fleet and prioritize devices still exposed on ws://.
- Correlate central system message logs with device-side crashes to identify a hostile or compromised upstream server.
How to Mitigate CVE-2026-13217
Immediate Actions Required
- Update Zephyr OCPP-enabled firmware images to include both patch commits 4d8a9eb and 3a55507 before redeploying to charge points.
- Enforce OCPP over TLS (wss://) with mutual authentication to eliminate the man-in-the-middle path on affected devices.
- Restrict which central system endpoints charge points are allowed to reach at the network layer.
Patch Information
The Zephyr project addressed the initial NULL dereference in commit 4d8a9eb, which guards the first strtok_r() return value. A second commit, 3a55507, extends the guard to the second strtok_r() call in the same function. Both commits are required for a complete fix. Additional context is available in the Zephyr security advisory GHSA-w234-pcxp-4q8r.
Workarounds
- Disable the OCPP 1.6 client subsystem in Zephyr builds where it is not required until patched firmware is deployed.
- Terminate OCPP traffic through an authenticated reverse proxy that validates uid fields on CALLRESULT frames and drops malformed messages.
- Disable CONFIG_NULL_POINTER_EXCEPTION_DETECTION only when combined with the upstream patches, since the platform-conditional impact still leaves undefined behavior on non-trapping targets.
# Apply upstream fixes to a local Zephyr checkout
cd zephyr
git fetch origin
git cherry-pick 4d8a9eb1448061ccee557ef20a2a58aec91d9cad
git cherry-pick 3a55507dd8011d877dc89eff949e70b42d45bacf
# Rebuild firmware for the target board
west build -b <board> samples/net/ocpp -p always
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

