http: allow configuration of request and response body inspection limits. Issue #560.

pull/146/head
Victor Julien 13 years ago
parent b99f9fe890
commit 2763a61213

@ -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)) {

@ -39,8 +39,12 @@
#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) */

@ -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 {

@ -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 {

@ -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

Loading…
Cancel
Save