]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #956 in SNORT/snort3 from nhttp81 to master
authorTom Peters (thopeter) <thopeter@cisco.com>
Fri, 14 Jul 2017 15:51:35 +0000 (11:51 -0400)
committerTom Peters (thopeter) <thopeter@cisco.com>
Fri, 14 Jul 2017 15:51:35 +0000 (11:51 -0400)
Squashed commit of the following:

commit 70455188e2954b95107457eefe85937439c271b5
Author: Tom Peters <thopeter@cisco.com>
Date:   Mon Jul 10 12:26:42 2017 -0400

    http_inspect: specific alert added 119:95 for Content-Encoding chunked.
    http_inspect: alert 119:96 added for unsolicited 206 response.
    file_api: memory leak fixed

src/file_api/file_policy.cc
src/service_inspectors/http_inspect/http_enum.h
src/service_inspectors/http_inspect/http_msg_header.cc
src/service_inspectors/http_inspect/http_msg_status.cc
src/service_inspectors/http_inspect/http_tables.cc
src/service_inspectors/http_inspect/http_test_input.cc
src/service_inspectors/http_inspect/http_uri.cc
src/service_inspectors/http_inspect/http_uri.h
src/service_inspectors/http_inspect/test/http_normalizers_test.cc

index fe98106f14c9b7534a4675ab12ec1245f76e46f1..42f54fde99df35243c3389f9bb46ad834c348512 100644 (file)
@@ -188,6 +188,8 @@ FileVerdict FilePolicy::signature_lookup(Flow* flow, FileContext* file)
 
         if (file->reserve_file(captured) == FILE_CAPTURE_SUCCESS)
             captured->store_file_async();
+        else
+            delete captured;
     }
 
     return (signature_lookup(flow, (FileInfo*)file));
index 4424fc066b8c2dbfeed53f8521fbd760ba2b4dd3..31cd6bbdcd9ed833aec92a2c3f6e869a3a11d0a5 100644 (file)
@@ -208,7 +208,7 @@ enum Infraction
     INF_JS_OBFUSCATION_EXCD,
     INF_JS_EXCESS_WS,
     INF_MIXED_ENCODINGS,
-    INF_RSP_WO_REQ,
+    INF_RESPONSE_WO_REQUEST,
     INF_SWF_ZLIB_FAILURE,
     INF_SWF_LZMA_FAILURE,
     INF_PDF_DEFL_FAILURE,
@@ -228,6 +228,8 @@ enum Infraction
     INF_CTE_HEADER,
     INF_ILLEGAL_TRAILER,
     INF_REPEATED_HEADER,
+    INF_CONTENT_ENCODING_CHUNKED,
+    INF_206_WITHOUT_RANGE,
     INF__MAX_VALUE
 };
 
@@ -237,7 +239,7 @@ enum CharAction { CHAR_NORMAL=2, CHAR_PERCENT, CHAR_PATH, CHAR_EIGHTBIT, CHAR_SU
 // Content codings
 enum Contentcoding { CONTENTCODE__OTHER=1, CONTENTCODE_GZIP, CONTENTCODE_DEFLATE,
     CONTENTCODE_COMPRESS, CONTENTCODE_EXI, CONTENTCODE_PACK200_GZIP, CONTENTCODE_X_GZIP,
-    CONTENTCODE_X_COMPRESS, CONTENTCODE_IDENTITY };
+    CONTENTCODE_X_COMPRESS, CONTENTCODE_IDENTITY, CONTENTCODE_CHUNKED };
 
 enum EventSid
 {
@@ -336,6 +338,8 @@ enum EventSid
     EVENT_CTE_HEADER,
     EVENT_ILLEGAL_TRAILER,
     EVENT_REPEATED_HEADER,
+    EVENT_CONTENT_ENCODING_CHUNKED,
+    EVENT_206_WITHOUT_RANGE,
     EVENT__MAX_VALUE
 };
 
index 50b779c8c1c4de825d84fb70fc592ddd23fddf59..5657b8020c37dba828f590684f52145256e4a417 100644 (file)
@@ -337,6 +337,10 @@ void HttpMsgHeader::setup_encoding_decompression()
             break;
         case CONTENTCODE_IDENTITY:
             break;
+        case CONTENTCODE_CHUNKED:
+            add_infraction(INF_CONTENT_ENCODING_CHUNKED);
+            create_event(EVENT_CONTENT_ENCODING_CHUNKED);
+            break;
         case CONTENTCODE__OTHER:
             add_infraction(INF_UNKNOWN_ENCODING);
             create_event(EVENT_UNKNOWN_ENCODING);
index 19b3470db73d3882059ae4124cd678c0508869d5..d5680b75fd7b03b9905cf4024de683845c5be07a 100644 (file)
@@ -153,10 +153,22 @@ void HttpMsgStatus::gen_events()
         if (flow->is_pdu_inorder(SSN_DIR_FROM_SERVER))
         {
             // HTTP response without a request. Possible ssh tunneling
-            add_infraction(INF_RSP_WO_REQ);
+            add_infraction(INF_RESPONSE_WO_REQUEST);
             create_event(EVENT_RESPONSE_WO_REQUEST);
         }
     }
+
+    if (status_code_num == 206)
+    {
+        // Verify that 206 Partial Content is in response to a Range request. Unsolicited 206
+        // responses indicate content is being fragmented for no good reason.
+        HttpMsgHeader* const req_header = transaction->get_header(SRC_CLIENT);
+        if ((req_header != nullptr) && (req_header->get_header_count(HEAD_RANGE) == 0))
+        {
+            add_infraction(INF_206_WITHOUT_RANGE);
+            create_event(EVENT_206_WITHOUT_RANGE);
+        }
+    }
 }
 
 void HttpMsgStatus::update_flow()
index 9c5bde32c199ba437ea66b7bba1997dd90c56b33..ab1f2ec75bbe60be17761489bbd0e635375aeaad 100644 (file)
@@ -148,6 +148,7 @@ const StrCode HttpMsgHeadShared::content_code_list[] =
     { CONTENTCODE_X_GZIP,        "x-gzip" },
     { CONTENTCODE_X_COMPRESS,    "x-compress" },
     { CONTENTCODE_IDENTITY,      "identity" },
+    { CONTENTCODE_CHUNKED,       "chunked" },
     { 0,                         nullptr }
 };
 
@@ -374,6 +375,8 @@ const RuleMap HttpModule::http_events[] =
     { EVENT_ILLEGAL_TRAILER,            "illegal field in chunked message trailers" },
     { EVENT_REPEATED_HEADER,            "header field inappropriately appears twice or has two "
                                         "values" },
+    { 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" },
     { 0, nullptr }
 };
 
index 7390d308e8a7975e460704343bd746ceb8417d04..ee6873b22eb3379ee56aeb36b25c7c2c7cda8d07 100644 (file)
@@ -254,10 +254,9 @@ void HttpTestInput::scan(uint8_t*& data, uint32_t& length, SourceId source_id, u
                     const unsigned amount = convert_num_octets(command_value + strlen("fileread"),
                         command_length - strlen("fileread"));
                     assert((amount > 0) && (amount <= MAX_OCTETS));
-                    int new_octet;
                     for (unsigned k=0; k < amount; k++)
                     {
-                        new_octet = getc(include_file);
+                        const int new_octet = getc(include_file);
                         assert(new_octet != EOF);
                         msg_buf[end_offset++] = new_octet;
                     }
index 4b427a25be21d2997a057d4341296613e835bf46..df5f5690ea9b887df89d1daefbc65566e7899824 100644 (file)
@@ -144,7 +144,7 @@ void HttpUri::parse_abs_path()
     }
 }
 
-void HttpUri::check_oversize_dir(Field uri_field)
+void HttpUri::check_oversize_dir(Field& uri_field)
 {
     int32_t total_length = 0;
     const uint8_t* last_dir = nullptr;
index 327e3e49081e5d7614f6c4dc76a6594a907e15fe..d61421e65f7335eb2b0778c0d2e4973daf039e17 100644 (file)
@@ -87,7 +87,7 @@ private:
     void parse_authority();
     void parse_abs_path();
 
-    void check_oversize_dir(Field);
+    void check_oversize_dir(Field&);
 };
 
 #endif
index 4c100c84a035629888affa4e7bd1a061ef5a754d..e0910ce1457ae9fa7bc4d9b61004a038c3377aaf 100644 (file)
@@ -49,7 +49,6 @@ TEST(norm_decimal_integer_test, examples)
     CHECK(norm_decimal_integer(Field(2, (const uint8_t*)"-27")) == STAT_PROBLEMATIC);
     CHECK(norm_decimal_integer(Field(6, (const uint8_t*)"27,382")) == 27);
     CHECK(norm_decimal_integer(Field(3, (const uint8_t*)",27")) == STAT_PROBLEMATIC);
-    CHECK(norm_decimal_integer(Field(3, (const uint8_t*)",27")) == STAT_PROBLEMATIC);
     CHECK(norm_decimal_integer(Field(6, (const uint8_t*)"00000=")) == STAT_PROBLEMATIC);
     CHECK(norm_decimal_integer(Field(6, (const uint8_t*)"32.578")) == STAT_PROBLEMATIC);
     CHECK(norm_decimal_integer(Field(18, (const uint8_t*)"123456789012345678")) ==