From: Victor Julien Date: Wed, 17 Oct 2012 16:15:37 +0000 (+0200) Subject: http: allow configuration of request and response body inspection limits. Issue ... X-Git-Tag: suricata-1.4beta3~72 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2763a61213f345ffe09c2a63a5a7a15573d0f275;p=thirdparty%2Fsuricata.git http: allow configuration of request and response body inspection limits. Issue #560. --- diff --git a/src/app-layer-htp.c b/src/app-layer-htp.c index 62f81da152..674dd7d9ee 100644 --- a/src/app-layer-htp.c +++ b/src/app-layer-htp.c @@ -74,16 +74,6 @@ //#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)) { diff --git a/src/app-layer-htp.h b/src/app-layer-htp.h index 8ee199a63d..69ae35630e 100644 --- a/src/app-layer-htp.h +++ b/src/app-layer-htp.h @@ -39,8 +39,12 @@ #include /* 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) */ diff --git a/src/detect-engine-hcbd.c b/src/detect-engine-hcbd.c index 45861275fd..461baa2cb2 100644 --- a/src/detect-engine-hcbd.c +++ b/src/detect-engine-hcbd.c @@ -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 { diff --git a/src/detect-engine-hsbd.c b/src/detect-engine-hsbd.c index 49b1f46882..9adc9298bb 100644 --- a/src/detect-engine-hsbd.c +++ b/src/detect-engine-hsbd.c @@ -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 { diff --git a/suricata.yaml.in b/suricata.yaml.in index 1aa9e57093..d68075cd85 100644 --- a/suricata.yaml.in +++ b/suricata.yaml.in @@ -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