From: Philippe Antoine Date: Tue, 7 Nov 2023 16:23:23 +0000 (+0100) Subject: http2: app-layer event for userinfo in uri X-Git-Tag: suricata-6.0.16~22 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=24404135e9b6cf7bf889ef831769402e55e7b720;p=thirdparty%2Fsuricata.git http2: app-layer event for userinfo in uri Ticket: #6426 as per RFC 9113 ":authority" MUST NOT include the deprecated userinfo subcomponent for "http" or "https" schemed URIs. (cherry picked from commit e3cd0d073f18a9d760e332852d53bce080ea96f0) --- diff --git a/rules/http2-events.rules b/rules/http2-events.rules index b2d6afc473..a1d6bae7d3 100644 --- a/rules/http2-events.rules +++ b/rules/http2-events.rules @@ -16,3 +16,4 @@ alert http2 any any -> any any (msg:"SURICATA HTTP2 stream identifier reuse"; fl alert http2 any any -> any any (msg:"SURICATA HTTP2 invalid HTTP1 settings during upgrade"; flow:established; app-layer-event:http2.invalid_http1_settings; classtype:protocol-command-decode; sid:2290008; rev:1;) alert http2 any any -> any any (msg:"SURICATA HTTP2 failed decompression"; flow:established; app-layer-event:http2.failed_decompression; classtype:protocol-command-decode; sid:2290009; 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;) +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;) diff --git a/rust/src/http2/http2.rs b/rust/src/http2/http2.rs index e5edcda48e..9df9488cda 100644 --- a/rust/src/http2/http2.rs +++ b/rust/src/http2/http2.rs @@ -189,6 +189,11 @@ impl HTTP2Transaction { self.decoder.http2_encoding_fromvec(&block.value, _dir); } else if block.name.eq_ignore_ascii_case(b":authority") { authority = Some(&block.value); + if block.value.iter().any(|&x| x == b'@') { + // it is forbidden by RFC 9113 to have userinfo in this field + // when in HTTP1 we can have user:password@domain.com + self.set_event(HTTP2Event::UserinfoInUri); + } } else if block.name.eq_ignore_ascii_case(b"host") { host = Some(&block.value); } @@ -355,6 +360,7 @@ pub enum HTTP2Event { InvalidHTTP1Settings, FailedDecompression, AuthorityHostMismatch, + UserinfoInUri, } impl HTTP2Event { @@ -371,6 +377,7 @@ impl HTTP2Event { 8 => Some(HTTP2Event::InvalidHTTP1Settings), 9 => Some(HTTP2Event::FailedDecompression), 10 => Some(HTTP2Event::AuthorityHostMismatch), + 11 => Some(HTTP2Event::UserinfoInUri), _ => None, } } @@ -1167,6 +1174,7 @@ pub extern "C" fn rs_http2_state_get_event_info( "invalid_http1_settings" => HTTP2Event::InvalidHTTP1Settings as i32, "failed_decompression" => HTTP2Event::FailedDecompression as i32, "authority_host_mismatch" => HTTP2Event::AuthorityHostMismatch as i32, + "userinfo_in_uri" => HTTP2Event::UserinfoInUri as i32, _ => -1, // unknown event } } @@ -1197,6 +1205,7 @@ pub extern "C" fn rs_http2_state_get_event_info_by_id( HTTP2Event::InvalidHTTP1Settings => "invalid_http1_settings\0", HTTP2Event::FailedDecompression => "failed_decompression\0", HTTP2Event::AuthorityHostMismatch => "authority_host_mismatch\0", + HTTP2Event::UserinfoInUri => "userinfo_in_uri\0", }; unsafe { *event_name = estr.as_ptr() as *const std::os::raw::c_char;