Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-13217

CVE-2026-13217: Zephyr OCPP 1.6 Client DOS Vulnerability

CVE-2026-13217 is a denial of service flaw in Zephyr OCPP 1.6 client caused by NULL pointer dereference when processing malformed CALLRESULT messages. This post explains its impact, affected components, and mitigation steps.

Published:

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.

c
// 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

c
// 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.
bash
# 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.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.