]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #1161 in SNORT/snort3 from nhttp98 to master
authorTom Peters (thopeter) <thopeter@cisco.com>
Mon, 26 Mar 2018 19:20:01 +0000 (15:20 -0400)
committerTom Peters (thopeter) <thopeter@cisco.com>
Mon, 26 Mar 2018 19:20:01 +0000 (15:20 -0400)
Squashed commit of the following:

commit 8327dad829a8c31f1c61c319480fb4498cd54c10
Author: Tom Peters <thopeter@cisco.com>
Date:   Fri Mar 23 16:11:55 2018 -0400

    http_inspect: embedded white space in Content-Length

src/service_inspectors/http_inspect/http_enum.h
src/service_inspectors/http_inspect/http_header_normalizer.cc
src/service_inspectors/http_inspect/http_header_normalizer.h
src/service_inspectors/http_inspect/http_tables.cc

index 01afd9f78e68fbbecb26275bab346bb32a2bfac8..b21f4232e85af4e48d19191dd896f719e4f5258b 100644 (file)
@@ -232,6 +232,7 @@ enum Infraction
     INF_206_WITHOUT_RANGE,
     INF_VERSION_NOT_UPPERCASE,
     INF_CHUNK_LEADING_WS,
+    INF_BAD_HEADER_WHITESPACE,
     INF__MAX_VALUE
 };
 
@@ -343,6 +344,7 @@ enum EventSid
     EVENT_CONTENT_ENCODING_CHUNKED,
     EVENT_206_WITHOUT_RANGE,
     EVENT_VERSION_NOT_UPPERCASE,
+    EVENT_BAD_HEADER_WHITESPACE,
     EVENT__MAX_VALUE
 };
 
index e4e1f9a563296f07318b2191754c43bcf8fb4c90..0b3e4aaba3a99d83cb2de59e667a667aadb61aeb 100644 (file)
@@ -21,6 +21,7 @@
 #include "config.h"
 #endif
 
+#include "http_enum.h"
 #include "http_header_normalizer.h"
 
 #include <cstring>
@@ -29,15 +30,23 @@ using namespace HttpEnums;
 
 // This derivation removes leading and trailing linear white space and replaces internal strings of
 // linear whitespace with a single <SP>
-int32_t HeaderNormalizer::derive_header_content(const uint8_t* value, int32_t length,
-    uint8_t* buffer)
+static int32_t derive_header_content(const uint8_t* value, int32_t length, uint8_t* buffer,
+    bool alert_ws, HttpInfractions* infractions, HttpEventGen* events)
 {
     int32_t out_length = 0;
+    bool beginning = true;
     bool last_white = true;
     for (int32_t k=0; k < length; k++)
     {
         if (!is_sp_tab_cr_lf[value[k]])
         {
+            if (alert_ws && last_white && !beginning)
+            {
+                // white space which is not at beginning or end
+                *infractions += INF_BAD_HEADER_WHITESPACE;
+                events->create_event(EVENT_BAD_HEADER_WHITESPACE);
+            }
+            beginning = false;
             last_white = false;
             buffer[out_length++] = value[k];
         }
@@ -99,8 +108,8 @@ void HeaderNormalizer::normalize(const HeaderId head_id, const int count,
     // number of normalization functions is odd or even, the initial buffer is chosen so that the
     // final normalization leaves the normalized header value in norm_value.
 
-    uint8_t* const norm_value = new uint8_t[buffer_length]();
-    uint8_t* const temp_space = new uint8_t[buffer_length]();
+    uint8_t* const norm_value = new uint8_t[buffer_length];
+    uint8_t* const temp_space = new uint8_t[buffer_length];
     uint8_t* const norm_start = (num_normalizers%2 == 0) ? norm_value : temp_space;
     uint8_t* working = norm_start;
     int32_t data_length = 0;
@@ -113,7 +122,7 @@ void HeaderNormalizer::normalize(const HeaderId head_id, const int count,
             while (header_name_id[++curr_match] != head_id);
         }
         int32_t growth = derive_header_content(header_value[curr_match].start(),
-            header_value[curr_match].length(), working);
+            header_value[curr_match].length(), working, alert_ws, infractions, events);
         working += growth;
         data_length += growth;
     }
index 4ef3c2d9183e15f81f5521b8321bf28fb2f47abd..d0663e89b776d6b4e9cc26c3f79487147bb77ce1 100644 (file)
@@ -39,8 +39,10 @@ class HeaderNormalizer
 {
 public:
     constexpr HeaderNormalizer(HttpEnums::EventSid _repeat_event,
-        HttpEnums::Infraction _repeat_inf, NormFunc* f1, NormFunc* f2, NormFunc* f3)
-        : repeat_event(_repeat_event), repeat_inf(_repeat_inf), normalizer { f1, f2, f3 },
+        HttpEnums::Infraction _repeat_inf, bool _alert_ws,
+        NormFunc* f1, NormFunc* f2, NormFunc* f3)
+        : repeat_event(_repeat_event), repeat_inf(_repeat_inf), alert_ws(_alert_ws),
+        normalizer { f1, f2, f3 },
         num_normalizers((f1 != nullptr) + (f1 != nullptr)*(f2 != nullptr) + (f1 != nullptr)*(f2 !=
             nullptr)*(f3 != nullptr)) { }
 
@@ -50,10 +52,9 @@ public:
         const int32_t num_headers, Field& result_field) const;
 
 private:
-    static int32_t derive_header_content(const uint8_t* value, int32_t length, uint8_t* buffer);
-
     const HttpEnums::EventSid repeat_event;
     const HttpEnums::Infraction repeat_inf;
+    const bool alert_ws;  // alert if white space in middle of value
     NormFunc* const normalizer[3];
     const int num_normalizers;
 };
index 34ad981fc3d624e97cd00a21014fda3ad9b1ee14..71c3385eb54770982d9e9d6e37fdb124a826798d 100644 (file)
@@ -172,39 +172,39 @@ const StrCode HttpMsgHeadShared::charset_code_opt_list[] =
 };
 
 const HeaderNormalizer HttpMsgHeadShared::NORMALIZER_BASIC
-    { EVENT__NONE, INF__NONE, nullptr, nullptr, nullptr };
+    { EVENT__NONE, INF__NONE, false, nullptr, nullptr, nullptr };
 
 const HeaderNormalizer HttpMsgHeadShared::NORMALIZER_NO_REPEAT
-    { EVENT_REPEATED_HEADER, INF_REPEATED_HEADER, nullptr, nullptr, nullptr };
+    { EVENT_REPEATED_HEADER, INF_REPEATED_HEADER, false, nullptr, nullptr, nullptr };
 
 const HeaderNormalizer HttpMsgHeadShared::NORMALIZER_CASE_INSENSITIVE
-    { EVENT__NONE, INF__NONE, norm_to_lower, nullptr, nullptr };
+    { EVENT__NONE, INF__NONE, false, norm_to_lower, nullptr, nullptr };
 
 const HeaderNormalizer HttpMsgHeadShared::NORMALIZER_NUMBER
-    { EVENT_REPEATED_HEADER, INF_REPEATED_HEADER, norm_remove_lws, nullptr, nullptr };
+    { EVENT_REPEATED_HEADER, INF_REPEATED_HEADER, false, norm_remove_lws, nullptr, nullptr };
 
 const HeaderNormalizer HttpMsgHeadShared::NORMALIZER_TOKEN_LIST
-    { EVENT__NONE, INF__NONE, norm_remove_lws, norm_to_lower, nullptr };
+    { EVENT__NONE, INF__NONE, false, norm_remove_lws, norm_to_lower, nullptr };
 
 const HeaderNormalizer HttpMsgHeadShared::NORMALIZER_METHOD_LIST
-    { EVENT__NONE, INF__NONE, norm_remove_lws, nullptr, nullptr };
+    { EVENT__NONE, INF__NONE, false, norm_remove_lws, nullptr, nullptr };
 
 // FIXIT-L implement a date normalization function that converts the three legal formats into a
 // single standard format. For now we do nothing special for dates. This object is a placeholder
 // to keep track of which headers have date values.
 const HeaderNormalizer HttpMsgHeadShared::NORMALIZER_DATE
-    { EVENT__NONE, INF__NONE, nullptr, nullptr, nullptr };
+    { EVENT__NONE, INF__NONE, false, nullptr, nullptr, nullptr };
 
 // FIXIT-M implement a URI normalization function, probably by extending existing URI capabilities
 // to cover relative formats
 const HeaderNormalizer HttpMsgHeadShared::NORMALIZER_URI
-    { EVENT__NONE, INF__NONE, nullptr, nullptr, nullptr };
+    { EVENT__NONE, INF__NONE, false, nullptr, nullptr, nullptr };
 
 const HeaderNormalizer HttpMsgHeadShared::NORMALIZER_CONTENT_LENGTH
-    { EVENT_MULTIPLE_CONTLEN, INF_MULTIPLE_CONTLEN, norm_remove_lws, nullptr, nullptr };
+    { EVENT_MULTIPLE_CONTLEN, INF_MULTIPLE_CONTLEN, true, norm_remove_lws, nullptr, nullptr };
 
 const HeaderNormalizer HttpMsgHeadShared::NORMALIZER_CHARSET
-    { EVENT__NONE, INF__NONE, norm_remove_quotes_lws, norm_to_lower, nullptr };
+    { EVENT__NONE, INF__NONE, false, norm_remove_quotes_lws, norm_to_lower, nullptr };
 
 #if defined(__clang__)
 // Designated initializers are not supported in C++11. However we're going to play compilation
@@ -380,6 +380,7 @@ const snort::RuleMap HttpModule::http_events[] =
     { EVENT_CONTENT_ENCODING_CHUNKED,   "invalid value chunked in Content-Encoding header" },
     { EVENT_206_WITHOUT_RANGE,          "206 response sent to a request without a Range header" },
     { EVENT_VERSION_NOT_UPPERCASE,      "'HTTP' in version field not all upper case" },
+    { EVENT_BAD_HEADER_WHITESPACE,      "white space embedded in critical header value" },
     { 0, nullptr }
 };