Project

General

Profile

Actions

Security #8980

open
JI JI

dnp3: framing errors stop transaction inspection for the flow

Security #8980: dnp3: framing errors stop transaction inspection for the flow

Added by Jason Ish 2 days ago. Updated 10 minutes ago.

Status:
In Review
Priority:
Normal
Assignee:
Target version:
Affected Versions:
Label:
CVE:
Git IDs:
Severity:
LOW
Disclosure Date:
11/24/2026
GHSA:

Description

  1. Summary

Certain malformed DNP3 link-layer input can cause Suricata to stop producing
DNP3 transaction records for the remainder of the TCP connection.

When a stream begins with a frame containing a bad link-header CRC, no DNP3
record is emitted for that frame or for subsequent well-formed frames on the
same connection.

A related result occurs when a valid frame is followed by non-frame garbage:
the opening frame is reported, but subsequent valid frames are not.

  1. Affected versions

This was reproduced on:

- Suricata 7.0.17
- Suricata 8.0.3
- Suricata 8.0.6

  1. Impact

DNP3-over-TCP sessions are commonly long-lived. A monitor that starts or
restarts may encounter a connection that will not perform another TCP
handshake for an extended period.

If parsing stops after the first boundary-aligned malformed frame, later DNP3
activity on that connection is not represented by DNP3 transaction records or
transaction-aware inspection.

The malformed frame itself is detected internally, but when it precedes the
first transaction its decoder event is also discarded.

  1. Sentinel reproducer

The attached sentinel archive contains four captures. Each scenario is
followed by three additional well-formed DNP3 frames, each in its own TCP
segment and using distinct addresses.

Observed results:

Capture Sentinels reported Total DNP3 records
--- ---: ---:
Two valid frames, baseline 3 of 3 5
Bad link-header CRC, then valid frames 0 of 3 0
Bad data-block CRC, then valid frames 3 of 3 4
Valid frame, garbage, then valid frames 0 of 3 1

The bad data-block CRC case demonstrates that the loss is defect-specific and
that the parser can recover from some link-layer errors.

The valid-frame-then-garbage case demonstrates that the loss is not solely
caused by the malformed frame being first on the connection.

  1. Midstream scenario

With `stream.midstream` enabled, a boundary-aligned pickup of an established
connection reproduces the condition.

On 8.0.6, the midstream stream containing a valid frame before the defect
alerts, while the defect-first stream does not. The latter is detected as
DNP3, reaches the parser, logs the discarded-event warning, and produces no
alert.

Pickups beginning 5, 8, or 16 bytes into a frame instead fail protocol
detection. Those cases are outside this finding. The relevant scenario is a
pickup on a DNP3 frame boundary.

  1. Attacker model and limits

An attacker must be able to place bytes in the application stream of a
DNP3/TCP connection, either as an endpoint or from an on-path position capable
of injecting sequence-correct TCP data.

No DNP3 endpoint implementation was tested. It has therefore not been
demonstrated that a particular endpoint will discard the malformed frame,
remain connected, and process the subsequent valid frames. The demonstrated
impact is the loss of DNP3 transaction reporting within Suricata.

Expected behavior is for Suricata to report the malformed input and safely
resume inspection of subsequent valid DNP3 frames where resynchronization is
possible.

  1. Disclosure coordination

This behavior is described in an academic paper currently under submission.
Publication, if accepted, is not expected before December 2026. Coordination
or delay is available if required.


Files

sentinel-evidence.zip (3.21 KB) sentinel-evidence.zip Jason Ish, 08/31/2026 05:48 PM
midstream-test.zip (4.99 KB) midstream-test.zip Jason Ish, 08/31/2026 05:48 PM
build-info-8.0.6.txt (4.43 KB) build-info-8.0.6.txt Jason Ish, 08/31/2026 05:48 PM
build-info-8.0.3.txt (4.67 KB) build-info-8.0.3.txt Jason Ish, 08/31/2026 05:48 PM
build-info-7.0.17.txt (4.48 KB) build-info-7.0.17.txt Jason Ish, 08/31/2026 05:48 PM

Subtasks 1 (1 open0 closed)

Security #8981: dnp3: framing errors stop transaction inspection for the flow (8.0.x backport)AssignedJason IshActions

Related issues 1 (1 open0 closed)

Related to Suricata - Security #8979: dnp3: link-layer events before first transaction are droppedIn ReviewJason IshActions

JI Updated by Jason Ish 2 days ago Actions #1

  • Related to Security #8979: dnp3: link-layer events before first transaction are dropped added

JI Updated by Jason Ish 2 days ago Actions #2

  • Assignee changed from OISF Dev to Jason Ish

JI Updated by Jason Ish 2 days ago Actions #3

  • Status changed from New to In Progress
  • Target version set to 9.0.0-beta1
  • Label Needs backport to 8.0 added

OT Updated by OISF Ticketbot 2 days ago Actions #4

  • Subtask #8981 added

OT Updated by OISF Ticketbot 2 days ago Actions #5

  • Label deleted (Needs backport to 8.0)

JI Updated by Jason Ish 1 day ago Actions #6

  • Status changed from In Progress to In Review

PA Updated by Philippe Antoine 25 minutes ago Actions #7

  • Severity set to LOW

I propose LOW severity as an evasion on disabled-by-default DNP3

JI Updated by Jason Ish 15 minutes ago Actions #9

  • Private changed from Yes to No

JI Updated by Jason Ish 10 minutes ago Actions #10

AI review caught this,

Medium — src/app-layer-dnp3.c:1112 and src/app-layer-dnp3.c:1246: Invalid start bytes still terminate parsing, so the valid-frame → garbage → valid-frame reproducer from Redmine #8980 continues to suppress subsequent DNP3 inspection on long-lived flows. suricata-verify MR !178 does not cover this scenario. Resynchronize established DNP3 streams after non-frame garbage and add the ticket’s exact sequence as a regression test.

However, after internal discussion we're keeping this behavior.

Actions

Also available in: PDF Atom