diff --git a/README.md b/README.md index d638a0c..ddf548a 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ Further information about nginx third-party add-ons support are available [here] # Usage ModSecurity for nginx extends your nginx configuration directives. -It adds four new directives and they are: +It adds six new directives and they are: modsecurity ----------- @@ -175,6 +175,60 @@ using the same unique identificator. String can contain variables. +modsecurity_skip_req_body_filter +----------------- +**syntax:** *modsecurity_skip_req_body_filter on | off* + +**context:** *http, server, location* + +**default:** *off* + +Allows to skip the caching of the request body and subsequently its inspection. +Useful in cases, where `SecRequestBodyAccess` or `ctl:requestBodyAccess` is set, due to, e.g. encrypted data, as the caching causes an unneeded memory overhead. + + +```nginx +server { + modsecurity on; + modsecurity_rules_file /etc/my_modsecurity_rules.conf; + + location / { + root /var/www/html; + } + + location = /special/unchecked/path { + # skip the inspection of the request body + modsecurity_skip_req_body_filter on; + } +} +``` + +modsecurity_skip_resp_body_filter +----------------- +**syntax:** *modsecurity_skip_resp_body_filter on | off* + +**context:** *http, server, location* + +**default:** *off* + +Allows to skip the caching of the request body and subsequently its inspection. +Useful in cases, where `SecResponseBodyAccess` is set, due to, e.g. encrypted data, as the caching causes an unneeded memory overhead. + +```nginx +server { + modsecurity on; + modsecurity_rules_file /etc/my_modsecurity_rules.conf; + + location / { + root /var/www/html; + } + + location = /special/unchecked/path { + # skip the inspection of the response body + modsecurity_skip_resp_body_filter on; + } +} +``` # Contributing diff --git a/src/ngx_http_modsecurity_body_filter.c b/src/ngx_http_modsecurity_body_filter.c index 0c28e3c..320c77e 100644 --- a/src/ngx_http_modsecurity_body_filter.c +++ b/src/ngx_http_modsecurity_body_filter.c @@ -39,8 +39,8 @@ ngx_http_modsecurity_body_filter(ngx_http_request_t *r, ngx_chain_t *in) { ngx_chain_t *chain = in; ngx_http_modsecurity_ctx_t *ctx = NULL; + ngx_http_modsecurity_conf_t *mcf = NULL; #if defined(MODSECURITY_SANITY_CHECKS) && (MODSECURITY_SANITY_CHECKS) - ngx_http_modsecurity_conf_t *mcf; ngx_list_part_t *part = &r->headers_out.headers.part; ngx_table_elt_t *data = part->elts; ngx_uint_t i = 0; @@ -50,7 +50,19 @@ ngx_http_modsecurity_body_filter(ngx_http_request_t *r, ngx_chain_t *in) return ngx_http_next_body_filter(r, in); } - ctx = ngx_http_modsecurity_get_module_ctx(r); + mcf = ngx_http_get_module_loc_conf(r, ngx_http_modsecurity_module); + + if (mcf == NULL){ + dd("failed to get configuration"); + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + if (mcf->skip_resp_body_filter) { + dd("Skipping response body filter"); + return ngx_http_next_body_filter(r, in); + } + + ctx = ngx_http_get_module_ctx(r, ngx_http_modsecurity_module); dd("body filter, recovering ctx: %p", ctx); @@ -63,8 +75,7 @@ ngx_http_modsecurity_body_filter(ngx_http_request_t *r, ngx_chain_t *in) } #if defined(MODSECURITY_SANITY_CHECKS) && (MODSECURITY_SANITY_CHECKS) - mcf = ngx_http_get_module_loc_conf(r, ngx_http_modsecurity_module); - if (mcf != NULL && mcf->sanity_checks_enabled != NGX_CONF_UNSET) + if (mcf->sanity_checks_enabled != NGX_CONF_UNSET) { #if 0 dd("dumping stored ctx headers"); diff --git a/src/ngx_http_modsecurity_common.h b/src/ngx_http_modsecurity_common.h index a4687e8..54fba46 100644 --- a/src/ngx_http_modsecurity_common.h +++ b/src/ngx_http_modsecurity_common.h @@ -123,6 +123,8 @@ typedef struct { #endif ngx_http_complex_value_t *transaction_id; + ngx_flag_t skip_req_body_filter; + ngx_flag_t skip_resp_body_filter; } ngx_http_modsecurity_conf_t; diff --git a/src/ngx_http_modsecurity_module.c b/src/ngx_http_modsecurity_module.c index e8a5f4b..da68519 100644 --- a/src/ngx_http_modsecurity_module.c +++ b/src/ngx_http_modsecurity_module.c @@ -513,6 +513,22 @@ static ngx_command_t ngx_http_modsecurity_commands[] = { 0, NULL }, + { + ngx_string("modsecurity_skip_req_body_filter"), + NGX_HTTP_LOC_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_MAIN_CONF|NGX_CONF_FLAG, + ngx_conf_set_flag_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_modsecurity_conf_t, skip_req_body_filter), + NULL + }, + { + ngx_string("modsecurity_skip_resp_body_filter"), + NGX_HTTP_LOC_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_MAIN_CONF|NGX_CONF_FLAG, + ngx_conf_set_flag_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_modsecurity_conf_t, skip_resp_body_filter), + NULL + }, ngx_null_command }; @@ -724,6 +740,8 @@ ngx_http_modsecurity_create_conf(ngx_conf_t *cf) conf->rules_set = msc_create_rules_set(); conf->pool = cf->pool; conf->transaction_id = NGX_CONF_UNSET_PTR; + conf->skip_req_body_filter = NGX_CONF_UNSET; + conf->skip_resp_body_filter = NGX_CONF_UNSET; #if defined(MODSECURITY_SANITY_CHECKS) && (MODSECURITY_SANITY_CHECKS) conf->sanity_checks_enabled = NGX_CONF_UNSET; #endif @@ -763,6 +781,8 @@ ngx_http_modsecurity_merge_conf(ngx_conf_t *cf, void *parent, void *child) ngx_conf_merge_value(c->enable, p->enable, 0); ngx_conf_merge_ptr_value(c->transaction_id, p->transaction_id, NULL); + ngx_conf_merge_value(c->skip_req_body_filter, p->skip_req_body_filter, 0); + ngx_conf_merge_value(c->skip_resp_body_filter, p->skip_resp_body_filter, 0); #if defined(MODSECURITY_SANITY_CHECKS) && (MODSECURITY_SANITY_CHECKS) ngx_conf_merge_value(c->sanity_checks_enabled, p->sanity_checks_enabled, 0); #endif diff --git a/src/ngx_http_modsecurity_pre_access.c b/src/ngx_http_modsecurity_pre_access.c index 75ac45d..8de522d 100644 --- a/src/ngx_http_modsecurity_pre_access.c +++ b/src/ngx_http_modsecurity_pre_access.c @@ -58,6 +58,13 @@ ngx_http_modsecurity_pre_access_handler(ngx_http_request_t *r) dd("ModSecurity not enabled... returning"); return NGX_DECLINED; } + + if(mcf->skip_req_body_filter == 1) + { + dd("Skipping request body filter"); + return NGX_DECLINED; + } + /* * FIXME: * In order to perform some tests, let's accept everything.