]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
http: allow configuration of request and response body inspection limits. Issue ...
authorVictor Julien <victor@inliniac.net>
Wed, 17 Oct 2012 16:15:37 +0000 (18:15 +0200)
committerVictor Julien <victor@inliniac.net>
Wed, 17 Oct 2012 16:15:37 +0000 (18:15 +0200)
src/app-layer-htp.c
src/app-layer-htp.h
src/detect-engine-hcbd.c
src/detect-engine-hsbd.c
suricata.yaml.in

index 62f81da152e943896346a25014432465b1b019ce..674dd7d9ee7cf992e00078062fc2f388bb11bc3e 100644 (file)
 
 //#define PRINT
 
-/** Need a linked list in order to keep track of these */
-typedef struct HTPCfgRec_ {
-    htp_cfg_t           *cfg;
-    struct HTPCfgRec_   *next;
-
-    /** max size of the client body we inspect */
-    uint32_t            request_body_limit;
-    uint32_t            response_body_limit;
-} HTPCfgRec;
-
 /** Fast lookup tree (radix) for the various HTP configurations */
 static SCRadixTree *cfgtree;
 /** List of HTP configurations. */
@@ -582,6 +572,7 @@ static int HTPHandleRequestData(Flow *f, void *htp_state,
      * tree.  Failing that, the default HTP config is used.
      */
     if (NULL == hstate->connp ) {
+        HTPCfgRec *htp_cfg_rec = &cfglist;
         htp_cfg_t *htp = cfglist.cfg; /* Default to the global HTP config */
         SCRadixNode *cfgnode = NULL;
 
@@ -599,7 +590,7 @@ static int HTPHandleRequestData(Flow *f, void *htp_state,
         }
 
         if (cfgnode != NULL) {
-            HTPCfgRec *htp_cfg_rec = SC_RADIX_NODE_USERDATA(cfgnode, HTPCfgRec);
+            htp_cfg_rec = SC_RADIX_NODE_USERDATA(cfgnode, HTPCfgRec);
             if (htp_cfg_rec != NULL) {
                 htp = htp_cfg_rec->cfg;
                 SCLogDebug("LIBHTP using config: %p", htp);
@@ -626,6 +617,7 @@ static int HTPHandleRequestData(Flow *f, void *htp_state,
         }
 
         htp_connp_set_user_data(hstate->connp, (void *)hstate);
+        hstate->cfg = htp_cfg_rec;
 
         SCLogDebug("New hstate->connp %p", hstate->connp);
     }
@@ -2090,6 +2082,10 @@ static void HTPConfigSetDefaults(HTPCfgRec *cfg_prec)
 {
     cfg_prec->request_body_limit = HTP_CONFIG_DEFAULT_REQUEST_BODY_LIMIT;
     cfg_prec->response_body_limit = HTP_CONFIG_DEFAULT_RESPONSE_BODY_LIMIT;
+    cfg_prec->request_inspect_min_size = HTP_CONFIG_DEFAULT_REQUEST_INSPECT_MIN_SIZE;
+    cfg_prec->request_inspect_window = HTP_CONFIG_DEFAULT_REQUEST_INSPECT_WINDOW;
+    cfg_prec->response_inspect_min_size = HTP_CONFIG_DEFAULT_RESPONSE_INSPECT_MIN_SIZE;
+    cfg_prec->response_inspect_window = HTP_CONFIG_DEFAULT_RESPONSE_INSPECT_WINDOW;
     htp_config_register_request(cfg_prec->cfg, HTPCallbackRequest);
     htp_config_register_response(cfg_prec->cfg, HTPCallbackResponse);
 #ifdef HAVE_HTP_URI_NORMALIZE_HOOK
@@ -2180,6 +2176,33 @@ static void HTPConfigParseParameters(HTPCfgRec *cfg_prec, ConfNode *s,
                            "from conf file - %s.  Killing engine", p->val);
                 exit(EXIT_FAILURE);
             }
+        } else if (strcasecmp("request-body-minimal-inspect-size", p->name) == 0) {
+            if (ParseSizeStringU32(p->val, &cfg_prec->request_inspect_min_size) < 0) {
+                SCLogError(SC_ERR_SIZE_PARSE, "Error parsing request-body-minimal-inspect-size "
+                           "from conf file - %s.  Killing engine", p->val);
+                exit(EXIT_FAILURE);
+            }
+
+        } else if (strcasecmp("request-body-inspect-window", p->name) == 0) {
+            if (ParseSizeStringU32(p->val, &cfg_prec->request_inspect_window) < 0) {
+                SCLogError(SC_ERR_SIZE_PARSE, "Error parsing request-body-inspect-window "
+                           "from conf file - %s.  Killing engine", p->val);
+                exit(EXIT_FAILURE);
+            }
+
+        } else if (strcasecmp("response-body-minimal-inspect-size", p->name) == 0) {
+            if (ParseSizeStringU32(p->val, &cfg_prec->response_inspect_min_size) < 0) {
+                SCLogError(SC_ERR_SIZE_PARSE, "Error parsing response-body-minimal-inspect-size "
+                           "from conf file - %s.  Killing engine", p->val);
+                exit(EXIT_FAILURE);
+            }
+
+        } else if (strcasecmp("response-body-inspect-window", p->name) == 0) {
+            if (ParseSizeStringU32(p->val, &cfg_prec->response_inspect_window) < 0) {
+                SCLogError(SC_ERR_SIZE_PARSE, "Error parsing response-body-inspect-window "
+                           "from conf file - %s.  Killing engine", p->val);
+                exit(EXIT_FAILURE);
+            }
 
         } else if (strcasecmp("double-decode-path", p->name) == 0) {
             if (ConfValIsTrue(p->val)) {
index 8ee199a63d84d875247ee058aaf8b308845ab2ee..69ae35630e561b9d72c171ceb808d900ffef396a 100644 (file)
 #include <htp/htp.h>
 
 /* default request body limit */
-#define HTP_CONFIG_DEFAULT_REQUEST_BODY_LIMIT       4096U
-#define HTP_CONFIG_DEFAULT_RESPONSE_BODY_LIMIT      4096U
+#define HTP_CONFIG_DEFAULT_REQUEST_BODY_LIMIT           4096U
+#define HTP_CONFIG_DEFAULT_RESPONSE_BODY_LIMIT          4096U
+#define HTP_CONFIG_DEFAULT_REQUEST_INSPECT_MIN_SIZE     32768U
+#define HTP_CONFIG_DEFAULT_REQUEST_INSPECT_WINDOW       4096U
+#define HTP_CONFIG_DEFAULT_RESPONSE_INSPECT_MIN_SIZE    32768U
+#define HTP_CONFIG_DEFAULT_RESPONSE_INSPECT_WINDOW      4096U
 
 /** a boundary should be smaller in size */
 #define HTP_BOUNDARY_MAX                            200U
@@ -122,6 +126,22 @@ enum {
 #define HTP_PCRE_HAS_MATCH      0x02    /**< Flag to indicate that the chunks
                                              matched on some rule */
 
+/** Need a linked list in order to keep track of these */
+typedef struct HTPCfgRec_ {
+    htp_cfg_t           *cfg;
+    struct HTPCfgRec_   *next;
+
+    /** max size of the client body we inspect */
+    uint32_t            request_body_limit;
+    uint32_t            response_body_limit;
+
+    uint32_t            request_inspect_min_size;
+    uint32_t            request_inspect_window;
+
+    uint32_t            response_inspect_min_size;
+    uint32_t            response_inspect_window;
+} HTPCfgRec;
+
 /** Struct used to hold chunks of a body on a request */
 struct HtpBodyChunk_ {
     uint8_t *data;              /**< Pointer to the data of the chunk */
@@ -201,6 +221,7 @@ typedef struct HtpState_ {
     uint32_t response_body_limit;
     FileContainer *files_ts;
     FileContainer *files_tc;
+    struct HTPCfgRec_ *cfg;
 } HtpState;
 
 /** part of the engine needs the request body (e.g. http_client_body keyword) */
index 45861275fde33adb49be6bbee611cb5305fd64ec..461baa2cb25f8267aa8f802e2a36327633b97221 100644 (file)
@@ -55,9 +55,6 @@
 #include "app-layer-htp.h"
 #include "app-layer-protos.h"
 
-#define BODY_SCAN_WINDOW 4096
-#define BODY_MINIMAL_SIZE 32768
-
 #define BUFFER_STEP 50
 
 static inline int HCBDCreateSpace(DetectEngineThreadCtx *det_ctx, uint16_t size)
@@ -165,7 +162,7 @@ static uint8_t *DetectEngineHCBDGetBufferForTX(int tx_id,
 
     /* inspect the body if the transfer is complete or we have hit
      * our body size limit */
-    if (htud->request_body.content_len_so_far < BODY_MINIMAL_SIZE &&
+    if (htud->request_body.content_len_so_far < htp_state->cfg->request_inspect_min_size &&
         !(htud->tsflags & HTP_REQ_BODY_COMPLETE)) {
         SCLogDebug("we still haven't seen the entire request body.  "
                    "Let's defer body inspection till we see the "
@@ -178,7 +175,7 @@ static uint8_t *DetectEngineHCBDGetBufferForTX(int tx_id,
         /* see if we can filter out chunks */
         if (htud->request_body.body_inspected > 0) {
             if (cur->stream_offset < htud->request_body.body_inspected) {
-                if ((htud->request_body.body_inspected - cur->stream_offset) > BODY_SCAN_WINDOW) {
+                if ((htud->request_body.body_inspected - cur->stream_offset) > htp_state->cfg->request_inspect_min_size) {
                     cur = cur->next;
                     continue;
                 } else {
index 49b1f46882d0b9c1bf3e9253bc1d6a3afdf561d4..9adc9298bbac0d9f089428d231d4d241de30f719 100644 (file)
@@ -56,9 +56,6 @@
 #include "app-layer-htp.h"
 #include "app-layer-protos.h"
 
-#define BODY_SCAN_WINDOW 4096
-#define BODY_MINIMAL_SIZE 32768
-
 #define BUFFER_STEP 50
 
 static inline int HSBDCreateSpace(DetectEngineThreadCtx *det_ctx, uint16_t size)
@@ -166,7 +163,7 @@ static uint8_t *DetectEngineHSBDGetBufferForTX(int tx_id,
 
     /* inspect the body if the transfer is complete or we have hit
      * our body size limit */
-    if (htud->response_body.content_len_so_far < BODY_MINIMAL_SIZE &&
+    if (htud->response_body.content_len_so_far < htp_state->cfg->response_inspect_min_size &&
         !(htud->tcflags & HTP_RES_BODY_COMPLETE)) {
         SCLogDebug("we still haven't seen the entire response body.  "
                    "Let's defer body inspection till we see the "
@@ -179,7 +176,7 @@ static uint8_t *DetectEngineHSBDGetBufferForTX(int tx_id,
         /* see if we can filter out chunks */
         if (htud->response_body.body_inspected > 0) {
             if (cur->stream_offset < htud->response_body.body_inspected) {
-                if ((htud->response_body.body_inspected - cur->stream_offset) > BODY_SCAN_WINDOW) {
+                if ((htud->response_body.body_inspected - cur->stream_offset) > htp_state->cfg->response_inspect_window) {
                     cur = cur->next;
                     continue;
                 } else {
index 1aa9e57093b65bcd4d8299ad8d3d9adc1c3e1f6d..d68075cd852abe7ee257a86d9c12ab23f3c085ae 100644 (file)
@@ -893,10 +893,19 @@ libhtp:
 
    default-config:
      personality: IDS
+
      # Can be specified in kb, mb, gb.  Just a number indicates
      # it's in bytes.
      request-body-limit: 3072
      response-body-limit: 3072
+
+     # inspection limits
+     request-body-minimal-inspect-size: 32kb
+     request-body-inspect-window: 4kb
+     response-body-minimal-inspect-size: 32kb
+     response-body-inspect-window: 4kb
+
+     # decoding
      double-decode-path: no
      double-decode-query: no