Project

General

Profile

Actions

Security #8979

open
JI JI

dnp3: link-layer events before first transaction are dropped

Security #8979: dnp3: link-layer events before first transaction are dropped

Added by Jason Ish 2 days ago. Updated 15 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

The DNP3 parser detects link-layer anomalies such as a bad link CRC, bad
transport CRC, or a link length that is too small and attaches the resulting
decoder event to the current transaction.

When the anomaly occurs before any DNP3 transaction exists, there is no
transaction to which the event can be attached. The event is discarded, a
warning is logged, and the corresponding decoder-event rule does not alert.

The same malformed frame alerts when it follows a well-formed frame because a
current transaction then exists.

  1. Affected versions

This was reproduced on:

- Suricata 7.0.17
- Suricata 8.0.3
- Suricata 8.0.6

  1. Reproducer

The attached archive contains two matched suricata-verify tests:

- `dnp3-link-event-after-transaction`: control that alerts.
- `dnp3-link-event-before-transaction`: expected-behavior test that currently
fails.

The TCP payloads are:

after:
05640a43050006000948c0c08100009ce8
05640844010002004c6cc0c0016da0
05640a43030004006e47c0c08100009ce8
before:
05640844010002004c6cc0c0016da0
05640a43030004006e47c0c08100009ce8

The failing stream is a byte-exact suffix of the passing stream. The only
difference is the well-formed 17-byte frame prepended to the control.

Run with:

--set app-layer.protocols.dnp3.enabled=yes
--set app-layer.protocols.dnp3.detection-ports.dp=20000
--set stream.reassembly.randomize-chunk-size=no

and the stock `bad_link_crc` rule, SID 2270002.

Observed behavior:

- `after` produces one `SURICATA DNP3 Bad link CRC` alert.
- `before` produces no alert and logs:

Failed to set event, state or tx pointer was NULL.

Expected behavior is for both streams to produce the decoder-event alert.

  1. Scale

A generated campaign covered the cross product of:

- defect before or after a well-formed frame;
- 40 defect configurations;
- four TCP segmentation points.

Results:

Position Alerts Dropped-event warnings
--- ---: ---:
Opens with a well-formed frame, 160 streams 88 0
Opens with the defect, 160 streams 0 88

The 88 configurations that alert after a transaction are the same 88 that log
a discarded event before the first transaction.

  1. Mechanism

`DNP3SetEvent()` only attaches an event when `dnp3->curr` exists:

static void DNP3SetEvent(DNP3State *dnp3, uint8_t event)
{
if (dnp3 && dnp3->curr) {
SCAppLayerDecoderEventsSetEventRaw(
&dnp3->curr->tx_data.events, event);
dnp3->events++;
}
else {
SCLogWarning(
"Failed to set event, state or tx pointer was NULL.");
}
}

The link-layer anomaly checks run before the user-data handler reaches the
transaction allocator. Loading additional rules cannot recover the event
because the transaction event object is missing.

Possible fix directions are to provide a carrier transaction for
pre-transaction link-layer anomalies or to provide another inspectable event
path for these link-layer events.

  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

suricata-verify-tests.zip (10.8 KB) suricata-verify-tests.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 #8982: dnp3: link-layer events before first transaction are dropped (8.0.x backport)AssignedJason IshActions

Related issues 1 (1 open0 closed)

Related to Suricata - Security #8980: dnp3: framing errors stop transaction inspection for the flowIn ReviewJason IshActions

JI Updated by Jason Ish 2 days ago Actions #1

  • Related to Security #8980: dnp3: framing errors stop transaction inspection for the flow 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 #8982 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 16 minutes ago Actions #8

  • Severity set to LOW

LOW severity as small evasion on disabled by default DNP3

JI Updated by Jason Ish 15 minutes ago Actions #9

  • Private changed from Yes to No
Actions

Also available in: PDF Atom