]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
http: makes decompression time limit configurable
authorPhilippe Antoine <contact@catenacyber.fr>
Wed, 17 Feb 2021 08:37:57 +0000 (09:37 +0100)
committerVictor Julien <victor@inliniac.net>
Tue, 23 Feb 2021 08:59:37 +0000 (09:59 +0100)
(cherry picked from commit a04b5566a62d9d6967587f83dfaca89b5c33eb66)

configure.ac
doc/userguide/configuration/suricata-yaml.rst
src/app-layer-htp.c
src/app-layer-htp.h
suricata.yaml.in

index 5c6635c7985e67232abdcb553990fe3b89e54fed..c4eab636f9082520f3609144ec5430b27e6877f4 100644 (file)
         AC_CHECK_LIB([htp], [htp_config_set_lzma_memlimit],AC_DEFINE_UNQUOTED([HAVE_HTP_CONFIG_SET_LZMA_MEMLIMIT],[1],[Found htp_config_set_lzma_memlimit function in libhtp]) ,,[-lhtp])
         AC_CHECK_LIB([htp], [htp_config_set_lzma_layers],AC_DEFINE_UNQUOTED([HAVE_HTP_CONFIG_SET_LZMA_LAYERS],[1],[Found htp_config_set_lzma_layers function in libhtp]) ,,[-lhtp])
         AC_CHECK_LIB([htp], [htp_config_set_compression_bomb_limit],AC_DEFINE_UNQUOTED([HAVE_HTP_CONFIG_SET_COMPRESSION_BOMB_LIMIT],[1],[Found htp_config_set_compression_bomb_limit function in libhtp]) ,,[-lhtp])
+        AC_CHECK_LIB([htp], [htp_config_set_compression_time_limit],AC_DEFINE_UNQUOTED([HAVE_HTP_CONFIG_SET_COMPRESSION_TIME_LIMIT],[1],[Found htp_config_set_compression_time_limit function in libhtp]) ,,[-lhtp])
     ])
 
     if test "x$enable_non_bundled_htp" = "xno"; then
             AC_DEFINE_UNQUOTED([HAVE_HTP_CONFIG_SET_LZMA_MEMLIMIT],[1],[Assuming htp_config_set_lzma_memlimit function in bundled libhtp])
             AC_DEFINE_UNQUOTED([HAVE_HTP_CONFIG_SET_LZMA_LAYERS],[1],[Assuming htp_config_set_lzma_layers function in bundled libhtp])
             AC_DEFINE_UNQUOTED([HAVE_HTP_CONFIG_SET_COMPRESSION_BOMB_LIMIT],[1],[Assuming htp_config_set_compression_bomb_limit function in bundled libhtp])
+            AC_DEFINE_UNQUOTED([HAVE_HTP_CONFIG_SET_COMPRESSION_TIME_LIMIT],[1],[Assuming htp_config_set_compression_time_limit function in bundled libhtp])
         else
             echo
             echo "  ERROR: Libhtp is not bundled. Get libhtp by doing:"
index a976df4a609c67e9caef5b75808f5efafacbf744..a4fcd75fc0c65d7e6feeac1074f97715a7aa650d 100644 (file)
@@ -1366,12 +1366,26 @@ use of libhtp.
        # Maximum decompressed size with a compression ratio
        # above 2048 (only reachable by LZMA)
        #compression-bomb-limit: 1 Mb
+       # Maximum time spent decompressing a single transaction in usec
+       #decompression-time-limit: 100000
 
 Other parameters are customizable from Suricata.
 ::
 
-      #   double-decode-path:     Double decode path section of the URI
-      #   double-decode-query:    Double decode query section of the URI
+#   double-decode-path:     Double decode path section of the URI
+#   double-decode-query:    Double decode query section of the URI
+
+decompression-time-limit
+------------------------
+
+decompression-time-limit was implemented to avoid DOS by resource exhaustion
+on inputs such as decompression bombs (found by fuzzing).
+The lower the limit, the better the protection against DOS is, but this
+may also lead to false positives.
+In case the time limit is reached,
+the app-layer event ``http.compression_bomb`` is set
+(this event can also set from other conditions).
+This can happen on slow configurations (hardware, ASAN, etc...)
 
 Configure SMB (Rust)
 ~~~~~~~~~~~~~~~~~~~~
index 469fd2f1a799c63bca9735a8c76ad80e42a345e6..78a7380dbc40e439c2db6a7bafde4c492d0a397e 100644 (file)
@@ -2393,6 +2393,9 @@ static void HTPConfigSetDefaultsPhase1(HTPCfgRec *cfg_prec)
 #ifdef HAVE_HTP_CONFIG_SET_COMPRESSION_BOMB_LIMIT
     htp_config_set_compression_bomb_limit(cfg_prec->cfg,
                                           HTP_CONFIG_DEFAULT_COMPRESSION_BOMB_LIMIT);
+#endif
+#ifdef HAVE_HTP_CONFIG_SET_COMPRESSION_TIME_LIMIT
+    htp_config_set_compression_time_limit(cfg_prec->cfg, HTP_CONFIG_DEFAULT_COMPRESSION_TIME_LIMIT);
 #endif
     /* libhtp <= 0.5.9 doesn't use soft limit, but it's impossible to set
      * only the hard limit. So we set both here to the (current) htp defaults.
@@ -2746,6 +2749,19 @@ static void HTPConfigParseParameters(HTPCfgRec *cfg_prec, ConfNode *s,
             /* set default soft-limit with our new hard limit */
             SCLogConfig("Setting HTTP compression bomb limit to %"PRIu32" bytes", limit);
             htp_config_set_compression_bomb_limit(cfg_prec->cfg, (size_t)limit);
+#endif
+#ifdef HAVE_HTP_CONFIG_SET_COMPRESSION_TIME_LIMIT
+        } else if (strcasecmp("decompression-time-limit", p->name) == 0) {
+            uint32_t limit = 0;
+            // between 1 usec and 1 second
+            if (StringParseU32RangeCheck(&limit, 10, 0, p->val, 1, 1000000) < 0) {
+                FatalError(SC_ERR_SIZE_PARSE,
+                        "failed to parse 'decompression-time-limit' "
+                        "from conf file - %s.",
+                        p->val);
+            }
+            SCLogConfig("Setting HTTP decompression time limit to %" PRIu32 " usec", limit);
+            htp_config_set_compression_time_limit(cfg_prec->cfg, (size_t)limit);
 #endif
         } else if (strcasecmp("randomize-inspection-sizes", p->name) == 0) {
             if (!g_disable_randomness) {
index 2037e906551ad7c6a27fb332ec9fe46a7a3b6673..d6fa4f00954a67036f4ceeea614964ccbd71aa64 100644 (file)
@@ -56,6 +56,8 @@
 /* default libhtp lzma limit, taken from libhtp. */
 #define HTP_CONFIG_DEFAULT_LZMA_MEMLIMIT                1048576U
 #define HTP_CONFIG_DEFAULT_COMPRESSION_BOMB_LIMIT       1048576U
+// 100000 usec is 0.1 sec
+#define HTP_CONFIG_DEFAULT_COMPRESSION_TIME_LIMIT 100000
 
 #define HTP_CONFIG_DEFAULT_RANDOMIZE                    1
 #define HTP_CONFIG_DEFAULT_RANDOMIZE_RANGE              10
index 3f1bae8f11fd64b16b9123bbc31aa46bf11349ea..8534f7ee9d5a0ffac13a81e48b262460cbb02454 100644 (file)
@@ -897,6 +897,8 @@ app-layer:
            # Maximum decompressed size with a compression ratio
            # above 2048 (only LZMA can reach this ratio, deflate cannot)
            #compression-bomb-limit: 1mb
+           # Maximum time spent decompressing a single transaction in usec
+           #decompression-time-limit: 100000
 
          server-config: