From 46a46e5b1f4909446e6f727f41b2eaeb3cb34bbd Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Mon, 6 Nov 2023 16:38:27 +0100 Subject: [PATCH] http2: event on mismatch between authority and host Ticket: #6425 --- rules/http2-events.rules | 1 + rust/src/http2/http2.rs | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/rules/http2-events.rules b/rules/http2-events.rules index c7a88b0c2b8f..868943a77bed 100644 --- a/rules/http2-events.rules +++ b/rules/http2-events.rules @@ -18,3 +18,4 @@ alert http2 any any -> any any (msg:"SURICATA HTTP2 failed decompression"; flow: alert http2 any any -> any any (msg:"SURICATA HTTP2 invalid range header"; flow:established; app-layer-event:http2.invalid_range; classtype:protocol-command-decode; sid:2290010; rev:1;) alert http2 any any -> any any (msg:"SURICATA HTTP2 variable-length integer overflow"; flow:established; app-layer-event:http2.header_integer_overflow; classtype:protocol-command-decode; sid:2290011; rev:1;) alert http2 any any -> any any (msg:"SURICATA HTTP2 too many streams"; flow:established; app-layer-event:http2.too_many_streams; classtype:protocol-command-decode; sid:2290012; rev:1;) +alert http2 any any -> any any (msg:"SURICATA HTTP2 authority host mismatch"; flow:established,to_server; app-layer-event:http2.authority_host_mismatch; classtype:protocol-command-decode; sid:2290013; rev:1;) diff --git a/rust/src/http2/http2.rs b/rust/src/http2/http2.rs index 326030f9bbe3..bbaeddb40434 100644 --- a/rust/src/http2/http2.rs +++ b/rust/src/http2/http2.rs @@ -203,9 +203,25 @@ impl HTTP2Transaction { } fn handle_headers(&mut self, blocks: &[parser::HTTP2FrameHeaderBlock], dir: Direction) { + let mut authority = None; + let mut host = None; for block in blocks { if block.name == b"content-encoding" { self.decoder.http2_encoding_fromvec(&block.value, dir); + } else if block.name.eq_ignore_ascii_case(b":authority") { + authority = Some(&block.value); + } else if block.name.eq_ignore_ascii_case(b"host") { + host = Some(&block.value); + } + } + if let Some(a) = authority { + if let Some(h) = host { + if !a.eq_ignore_ascii_case(h) { + // The event is triggered only if both headers + // are in the same frame to avoid excessive + // complexity at runtime. + self.set_event(HTTP2Event::AuthorityHostMismatch); + } } } } @@ -383,6 +399,7 @@ pub enum HTTP2Event { InvalidRange, HeaderIntegerOverflow, TooManyStreams, + AuthorityHostMismatch, } pub struct HTTP2DynTable {