From: Philippe Antoine Date: Thu, 28 Mar 2024 10:15:51 +0000 (+0100) Subject: http2: do not log duplicate headers X-Git-Tag: suricata-6.0.19~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d24b37a103c04bb2667e449e080ba4c8e56bb019;p=thirdparty%2Fsuricata.git http2: do not log duplicate headers Ticket: 6900 And thus avoid DOS by logging a request using a compressed header block repeated many times and having a long value... (cherry picked from commit 03442c9071b8d863d26b609d54c6eacf4de9e340) --- diff --git a/rust/src/http2/logger.rs b/rust/src/http2/logger.rs index 7e15ffcaab..0e4f128ca9 100644 --- a/rust/src/http2/logger.rs +++ b/rust/src/http2/logger.rs @@ -19,7 +19,8 @@ use super::http2::{HTTP2Frame, HTTP2FrameTypeData, HTTP2Transaction}; use super::parser; use crate::jsonbuilder::{JsonBuilder, JsonError}; use std; -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; +use std::rc::Rc; #[derive(Hash, PartialEq, Eq, Debug)] enum HeaderName { @@ -35,10 +36,20 @@ fn log_http2_headers<'a>( blocks: &'a Vec, js: &mut JsonBuilder, common: &mut HashMap>, ) -> Result<(), JsonError> { + let mut logged_headers = HashSet::new(); for j in 0..blocks.len() { - js.start_object()?; + // delay js.start_object() because we skip suplicate headers match blocks[j].error { parser::HTTP2HeaderDecodeStatus::HTTP2HeaderDecodeSuccess => { + if Rc::strong_count(&blocks[j].name) > 2 { + // more than one reference in headers table + current headers + let ptr = Rc::as_ptr(&blocks[j].name) as usize; + if !logged_headers.insert(ptr) { + // only log once + continue; + } + } + js.start_object()?; js.set_string_from_bytes("name", &blocks[j].name)?; js.set_string_from_bytes("value", &blocks[j].value)?; if let Ok(name) = std::str::from_utf8(&blocks[j].name) { @@ -66,9 +77,11 @@ fn log_http2_headers<'a>( } } parser::HTTP2HeaderDecodeStatus::HTTP2HeaderDecodeSizeUpdate => { + js.start_object()?; js.set_uint("table_size_update", blocks[j].sizeupdate)?; } _ => { + js.start_object()?; js.set_string("error", &blocks[j].error.to_string())?; } }