]> 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 15:15:08 +0000 (16:15 +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 fe1e6f3a4a89a712198d8cd39b728ca96fd6ae33..dbbfc86397e7a802e044eff611a2cacf06cd6467 100644 (file)
         AC_EGREP_HEADER(htp_config_set_path_decode_u_encoding, htp/htp.h, AC_DEFINE_UNQUOTED([HAVE_HTP_SET_PATH_DECODE_U_ENCODING],[1],[Found usable htp_config_set_path_decode_u_encoding function in libhtp]) )
         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_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_RESPONSE_DECOMPRESSION_LAYER_LIMIT],[1],[Assuming htp_config_set_response_decompression_layer_limit function in bundled libhtp])
             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_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 037eaac92c0d1ea2e5dbf39526c807b0146fd8ca..f5fad5210962752712363517c9728ec5bc04c600 100644 (file)
@@ -1507,12 +1507,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 6f2c8d26708335b72230379f3895e52014ebce3b..d0882cb9292caac63da17b4327d108219461e09c 100644 (file)
@@ -2426,6 +2426,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.
@@ -2770,6 +2773,23 @@ 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;
+            if (ParseSizeStringU32(p->val, &limit) < 0) {
+                FatalError(SC_ERR_SIZE_PARSE,
+                        "failed to parse 'decompression-time-limit' "
+                        "from conf file - %s.",
+                        p->val);
+            }
+            // between 1 usec and 1 second
+            if (limit < 1 || limit > 1000000) {
+                FatalError(SC_ERR_SIZE_PARSE,
+                        "'decompression-time-limit' %s out of range. Min value: 1, max value: 1000000.", 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 b83b8c914da508fe5c137c77d3cabb4b842a1bb0..92d41f3b8610940bb89c3f745b26c6b24a7597f0 100644 (file)
@@ -54,6 +54,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 97beefad8570997d7c62314a508a5dc419c8b711..9c10b6939f869ad80a549a98c21ff43bd5e73b63 100644 (file)
@@ -895,6 +895,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: