From: Philippe Antoine Date: Wed, 7 Jun 2023 14:17:17 +0000 (+0200) Subject: detect/http2: do not escape ':' in header name or value X-Git-Tag: suricata-7.0.0-rc2~38 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7256ec8a6e1fff7f08789dd7498b6e3e9885afdd;p=thirdparty%2Fsuricata.git detect/http2: do not escape ':' in header name or value for keywords http.request_header and http.response_header Ticket: #5780 --- diff --git a/doc/userguide/rules/http2-keywords.rst b/doc/userguide/rules/http2-keywords.rst index f328932fb6..f02c54e5f5 100644 --- a/doc/userguide/rules/http2-keywords.rst +++ b/doc/userguide/rules/http2-keywords.rst @@ -115,7 +115,6 @@ http.request_header Match on the name and value of a HTTP2 request header from a HEADER frame (or PUSH_PROMISE or CONTINUATION). Name and value get concatenated by ": ", colon and space. -Each colon in the name or the value should be escaped as a double colon "::" for detection Examples:: @@ -132,7 +131,6 @@ http.response_header Match on the name and value of a HTTP2 response header from a HEADER frame (or PUSH_PROMISE or CONTINUATION). Name and value get concatenated by ": ", colon and space. -Each colon in the name or the value should be escaped as a double colon "::" for detection Examples:: diff --git a/rust/src/http2/detect.rs b/rust/src/http2/detect.rs index 642b0c8220..99261adc4c 100644 --- a/rust/src/http2/detect.rs +++ b/rust/src/http2/detect.rs @@ -713,21 +713,11 @@ pub unsafe extern "C" fn rs_http2_tx_get_header_value( fn http2_escape_header(blocks: &[parser::HTTP2FrameHeaderBlock], i: u32) -> Vec { //minimum size + 2 for escapes - let normalsize = blocks[i as usize].value.len() + 2 + blocks[i as usize].name.len() + 2; + let normalsize = blocks[i as usize].value.len() + 2 + blocks[i as usize].name.len(); let mut vec = Vec::with_capacity(normalsize); - for j in 0..blocks[i as usize].name.len() { - vec.push(blocks[i as usize].name[j]); - if blocks[i as usize].name[j] == b':' { - vec.push(b':'); - } - } + vec.extend_from_slice(&blocks[i as usize].name); vec.extend_from_slice(&[b':', b' ']); - for j in 0..blocks[i as usize].value.len() { - vec.push(blocks[i as usize].value[j]); - if blocks[i as usize].value[j] == b':' { - vec.push(b':'); - } - } + vec.extend_from_slice(&blocks[i as usize].value); return vec; } diff --git a/src/detect-http2.c b/src/detect-http2.c index 35d0dce3c4..380d655715 100644 --- a/src/detect-http2.c +++ b/src/detect-http2.c @@ -99,8 +99,6 @@ static int PrefilterMpmHttp2HeaderRegister(DetectEngineCtx *de_ctx, SigGroupHead static uint8_t DetectEngineInspectHttp2Header(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, const DetectEngineAppInspectionEngine *engine, const Signature *s, Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id); -static bool DetectHttp2RequestHeaderValidateCallback(const Signature *s, const char **sigerror); -static bool DetectHttp2ResponseHeaderValidateCallback(const Signature *s, const char **sigerror); #ifdef UNITTESTS void DetectHTTP2RegisterTests (void); @@ -218,8 +216,6 @@ void DetectHttp2Register(void) PrefilterMpmHttp2HeaderRegister, NULL, ALPROTO_HTTP2, HTTP2StateOpen); DetectAppLayerInspectEngineRegister2("http_request_header", ALPROTO_HTTP2, SIG_FLAG_TOSERVER, HTTP2StateOpen, DetectEngineInspectHttp2Header, NULL); - DetectBufferTypeRegisterValidateCallback( - "http_request_header", DetectHttp2RequestHeaderValidateCallback); DetectBufferTypeSetDescriptionByName("http_request_header", "HTTP header name and value"); g_http_request_header_buffer_id = DetectBufferTypeGetByName("http_request_header"); @@ -235,8 +231,6 @@ void DetectHttp2Register(void) PrefilterMpmHttp2HeaderRegister, NULL, ALPROTO_HTTP2, HTTP2StateOpen); DetectAppLayerInspectEngineRegister2("http_response_header", ALPROTO_HTTP2, SIG_FLAG_TOCLIENT, HTTP2StateOpen, DetectEngineInspectHttp2Header, NULL); - DetectBufferTypeRegisterValidateCallback( - "http_response_header", DetectHttp2ResponseHeaderValidateCallback); DetectBufferTypeSetDescriptionByName("http_response_header", "HTTP header name and value"); g_http_response_header_buffer_id = DetectBufferTypeGetByName("http_response_header"); @@ -939,72 +933,6 @@ static uint8_t DetectEngineInspectHttp2Header(DetectEngineCtx *de_ctx, return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; } -static bool DetectHttp2HeaderValidateCallback( - const Signature *s, const char **sigerror, int buffer_id) -{ - for (uint32_t x = 0; x < s->init_data->buffer_index; x++) { - if (s->init_data->buffers[x].id != (uint32_t)g_http_request_header_buffer_id && - s->init_data->buffers[x].id != (uint32_t)g_http_response_header_buffer_id) - continue; - const SigMatch *sm = s->init_data->buffers[x].head; - for (; sm != NULL; sm = sm->next) { - if (sm->type != DETECT_CONTENT) - continue; - const SigMatch *sm = s->init_data->buffers[x].head; - for (; sm != NULL; sm = sm->next) { - if (sm->type != DETECT_CONTENT) - continue; - const DetectContentData *cd = (DetectContentData *)sm->ctx; - bool escaped = false; - bool namevaluesep = false; - for (size_t i = 0; i < cd->content_len; ++i) { - if (escaped) { - if (cd->content[i] == ' ') { - if (namevaluesep) { - *sigerror = - "Invalid http2.header string : " - "': ' is a special sequence for separation between name " - "and value " - " and thus can only be present once"; - SCLogWarning("rule %u: %s", s->id, *sigerror); - return false; - } - namevaluesep = true; - } else if (cd->content[i] != ':') { - *sigerror = "Invalid http2.header string : " - "':' is an escaping character for itself, " - "or space for the separation between name and value"; - SCLogWarning("rule %u: %s", s->id, *sigerror); - return false; - } - escaped = false; - } else if (cd->content[i] == ':') { - escaped = true; - } - } - if (escaped) { - *sigerror = "Invalid http2.header string : " - "':' is an escaping character for itself, " - "or space for the separation between name and value"; - SCLogWarning("rule %u: %s", s->id, *sigerror); - return false; - } - } - } - } - return true; -} - -static bool DetectHttp2RequestHeaderValidateCallback(const Signature *s, const char **sigerror) -{ - return DetectHttp2HeaderValidateCallback(s, sigerror, g_http_request_header_buffer_id); -} - -static bool DetectHttp2ResponseHeaderValidateCallback(const Signature *s, const char **sigerror) -{ - return DetectHttp2HeaderValidateCallback(s, sigerror, g_http_response_header_buffer_id); -} - #ifdef UNITTESTS #include "tests/detect-http2.c" #endif