]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
detect/http2: do not escape ':' in header name or value
authorPhilippe Antoine <pantoine@oisf.net>
Wed, 7 Jun 2023 14:17:17 +0000 (16:17 +0200)
committerVictor Julien <vjulien@oisf.net>
Fri, 9 Jun 2023 09:44:31 +0000 (11:44 +0200)
for keywords http.request_header and http.response_header

Ticket: #5780

doc/userguide/rules/http2-keywords.rst
rust/src/http2/detect.rs
src/detect-http2.c

index f328932fb6d061e34a3a7fb10faee45e5774dc9f..f02c54e5f5435d6e3100c7a35017d46bbf8a98c1 100644 (file)
@@ -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::
 
index 642b0c8220907d6ac195f21af5f66e4b328fae1e..99261adc4c41cbfc37f7f60aa5538bef5db2dd8d 100644 (file)
@@ -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<u8> {
     //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;
 }
 
index 35d0dce3c425fa8a2bd7b5d9829b000861024c3a..380d655715d2fab6175fdf8bec619f80abdb1c48 100644 (file)
@@ -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