Security #8584
closeddns/mdns: forward compression pointers accepted
Description
- Summary
The DNS name parser accepts forward compression pointers. RFC 1035 section 4.1.4 requires compression pointers to point backwards to a previous occurrence. Suricata only validates the upper bound and detects immediate self-reference, but does not validate that the pointer offset is before the current position.
- Affected Code
File: `rust/src/dns/parser.rs:92-116`
The DNS parser is reused by mDNS via `rust/src/mdns/mdns.rs:39`.
```rust
let offset = usize::from(leader) & 0x3fff;
if offset > message.len() { // only validates upper bound
return Err(...);
}
// Does NOT validate offset < current_position
pos = &message[offset..];
```
- Impact
Real resolvers such as BIND and Unbound reject forward pointers. An attacker can construct DNS messages where Suricata resolves a different name than the actual resolver, evading `dns.query` content or PCRE rules.
- Suggested Fix
Add validation to enforce backwards-only pointers per RFC 1035:
```rust
if offset >= current_position { return Err(...); }
```
- Environment
Suricata main branch @ commit 367ca7f (post v8.0.1, May 15, 2026).
- Credit
Reported by Chris Ramos.
Files
JI Updated by Jason Ish about 1 month ago
- Description updated (diff)
- Severity deleted (
MODERATE) - Disclosure Date set to 05/19/2026
- Affected Versions deleted (
git main)
PA Updated by Philippe Antoine about 1 month ago
Real resolvers such as BIND and Unbound reject forward pointers
Suricata resolves a different name than the actual resolver
Well, if the real resolver rejects it, it would only lead to FP...
This is an example of strict vs relaxed parsing, where I would lend more towards the actual relaxed parsing
JI Updated by Jason Ish about 1 month ago
- File dns.pcap dns.pcap added
- File dns_forward_pointer_query.py dns_forward_pointer_query.py added
8.8.8.8 and dnsmasq appear to accept these forward pointers. See attached pcap.
JF Updated by Juliana Fajardini Reichow about 1 month ago
- Status changed from New to Triaged
JF Updated by Juliana Fajardini Reichow 25 days ago
- Status changed from Triaged to Rejected
- Assignee deleted (
OISF Dev) - Target version deleted (
TBD)
Rejecting as we understand that relaxed parsing is the way to go.
Jason will add an SV test showcasing this for DNS, to indicate that that's an allowed behavior.
JF Updated by Juliana Fajardini Reichow 25 days ago
- Private changed from Yes to No