diff --git a/rules/http2-events.rules b/rules/http2-events.rules index 413fdd652c..7509eb0ea6 100644 --- a/rules/http2-events.rules +++ b/rules/http2-events.rules @@ -21,3 +21,5 @@ alert http2 any any -> any any (msg:"SURICATA HTTP2 too many streams"; flow:esta 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;) alert http2 any any -> any any (msg:"SURICATA HTTP2 user info in uri"; flow:established,to_server; app-layer-event:http2.userinfo_in_uri; classtype:protocol-command-decode; sid:2290014; rev:1;) alert http2 any any -> any any (msg:"SURICATA HTTP2 reassembly limit reached"; flow:established; app-layer-event:http2.reassembly_limit_reached; classtype:protocol-command-decode; sid:2290015; rev:1;) +alert http2 any any -> any any (msg:"SURICATA HTTP2 dns request too long"; flow:established,to_server; app-layer-event:http2.dns_request_too_long; classtype:protocol-command-decode; sid:2290016; rev:1;) +alert http2 any any -> any any (msg:"SURICATA HTTP2 dns response too long"; flow:established,to_client; app-layer-event:http2.dns_response_too_long; classtype:protocol-command-decode; sid:2290017; rev:1;) diff --git a/rust/src/http2/http2.rs b/rust/src/http2/http2.rs index 8ed0157922..98214ff1a6 100644 --- a/rust/src/http2/http2.rs +++ b/rust/src/http2/http2.rs @@ -368,9 +368,19 @@ impl HTTP2Transaction { if unsafe { ALPROTO_DOH2 } != ALPROTO_UNKNOWN { // we store DNS response, and process it when complete if let Some(doh) = &mut self.doh { - if doh.is_doh_data[dir.index()] && doh.data_buf[dir.index()].len() < 0xFFFF { - // a DNS message is U16_MAX - doh.data_buf[dir.index()].extend_from_slice(decompressed); + if doh.is_doh_data[dir.index()] { + if doh.data_buf[dir.index()].len() + decompressed.len() <= 0xFFFF { + // a DNS message is U16_MAX + doh.data_buf[dir.index()].extend_from_slice(decompressed); + } else { + // stop processing further data + doh.is_doh_data[dir.index()] = false; + if dir == Direction::ToClient { + self.set_event(HTTP2Event::DnsResponseTooLong); + } else { + self.set_event(HTTP2Event::DnsRequestTooLong); + } + } } } } @@ -506,6 +516,8 @@ pub enum HTTP2Event { AuthorityHostMismatch, UserinfoInUri, ReassemblyLimitReached, + DnsRequestTooLong, + DnsResponseTooLong, } pub struct HTTP2DynTable {