mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-08-13 21:36:00 +03:00
Allow ability to force request body buffering to memory. Fixes MODSEC-2.
This commit is contained in:
parent
139d651bbf
commit
34798e9abe
8
CHANGES
8
CHANGES
@ -1,7 +1,13 @@
|
||||
03 Sep 2008 - trunk
|
||||
-------------------
|
||||
|
||||
* Integrate mlogc source.
|
||||
* Added ctl:requestBodyBuffering=on|off which, when enabled, will force
|
||||
the request body to be buffered and allow REQUEST_BODY to be inspected.
|
||||
Previously the REQUEST_BODY target was only populated if the request body
|
||||
was a parsable type (application/x-www-form-urlencoded or
|
||||
multipart/form-data) or was forced to be parsed via ctl:requestBodyProcessor.
|
||||
|
||||
* Integrated mlogc source.
|
||||
|
||||
* Fixed logging the hostname in the error_log which was logging the
|
||||
request hostname instead of the Apache resolved hostname.
|
||||
|
@ -45,6 +45,7 @@ void *create_directory_config(apr_pool_t *mp, char *path) {
|
||||
dcfg->is_enabled = NOT_SET;
|
||||
|
||||
dcfg->reqbody_access = NOT_SET;
|
||||
dcfg->reqbody_buffering = NOT_SET;
|
||||
dcfg->reqbody_inmemory_limit = NOT_SET;
|
||||
dcfg->reqbody_limit = NOT_SET;
|
||||
dcfg->reqbody_no_files_limit = NOT_SET;
|
||||
@ -236,6 +237,8 @@ void *merge_directory_configs(apr_pool_t *mp, void *_parent, void *_child) {
|
||||
/* IO parameters */
|
||||
merged->reqbody_access = (child->reqbody_access == NOT_SET
|
||||
? parent->reqbody_access : child->reqbody_access);
|
||||
merged->reqbody_buffering = (child->reqbody_buffering == NOT_SET
|
||||
? parent->reqbody_buffering : child->reqbody_buffering);
|
||||
merged->reqbody_inmemory_limit = (child->reqbody_inmemory_limit == NOT_SET
|
||||
? parent->reqbody_inmemory_limit : child->reqbody_inmemory_limit);
|
||||
merged->reqbody_limit = (child->reqbody_limit == NOT_SET
|
||||
@ -480,6 +483,7 @@ void init_directory_config(directory_config *dcfg) {
|
||||
if (dcfg->is_enabled == NOT_SET) dcfg->is_enabled = 0;
|
||||
|
||||
if (dcfg->reqbody_access == NOT_SET) dcfg->reqbody_access = 0;
|
||||
if (dcfg->reqbody_buffering == NOT_SET) dcfg->reqbody_buffering = 0;
|
||||
if (dcfg->reqbody_inmemory_limit == NOT_SET)
|
||||
dcfg->reqbody_inmemory_limit = REQUEST_BODY_DEFAULT_INMEMORY_LIMIT;
|
||||
if (dcfg->reqbody_limit == NOT_SET) dcfg->reqbody_limit = REQUEST_BODY_DEFAULT_LIMIT;
|
||||
|
@ -259,6 +259,12 @@ apr_status_t modsecurity_tx_init(modsec_rec *msr) {
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if we are forcing buffering, then use memory only. */
|
||||
if (msr->txcfg->reqbody_buffering) {
|
||||
msr->msc_reqbody_storage = MSC_REQBODY_MEMORY;
|
||||
msr->msc_reqbody_spilltodisk = 0;
|
||||
}
|
||||
|
||||
/* Initialise arguments */
|
||||
msr->arguments = apr_table_make(msr->mp, 32);
|
||||
if (msr->arguments == NULL) return -1;
|
||||
|
@ -362,6 +362,7 @@ struct directory_config {
|
||||
|
||||
int is_enabled;
|
||||
int reqbody_access;
|
||||
int reqbody_buffering;
|
||||
long int reqbody_inmemory_limit;
|
||||
long int reqbody_limit;
|
||||
long int reqbody_no_files_limit;
|
||||
|
@ -309,6 +309,9 @@ apr_status_t modsecurity_request_body_store(modsec_rec *msr,
|
||||
msr->msc_reqbody_processor);
|
||||
return -1;
|
||||
}
|
||||
} else if (msr->txcfg->reqbody_buffering) {
|
||||
/* Increase per-request data length counter if forcing buffering. */
|
||||
msr->msc_reqbody_no_files_length += length;
|
||||
}
|
||||
|
||||
/* Check that we are not over the request body no files limit. */
|
||||
@ -334,7 +337,7 @@ apr_status_t modsecurity_request_body_store(modsec_rec *msr,
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static apr_status_t modsecurity_request_body_end_urlencoded(modsec_rec *msr, char **error_msg) {
|
||||
static apr_status_t modsecurity_request_body_end_raw(modsec_rec *msr, char **error_msg) {
|
||||
msc_data_chunk **chunks, *one_chunk;
|
||||
char *d;
|
||||
int i, sofar;
|
||||
@ -394,6 +397,22 @@ static apr_status_t modsecurity_request_body_end_urlencoded(modsec_rec *msr, cha
|
||||
one_chunk->is_permanent = 1;
|
||||
*(const msc_data_chunk **)apr_array_push(msr->msc_reqbody_chunks) = one_chunk;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static apr_status_t modsecurity_request_body_end_urlencoded(modsec_rec *msr, char **error_msg) {
|
||||
int invalid_count = 0;
|
||||
|
||||
*error_msg = NULL;
|
||||
|
||||
/* Create the raw buffer */
|
||||
if (modsecurity_request_body_end_raw(msr, error_msg) != 1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Parse URL-encoded arguments in the request body. */
|
||||
|
||||
if (parse_arguments(msr, msr->msc_reqbody_buffer, msr->msc_reqbody_length,
|
||||
@ -458,6 +477,9 @@ apr_status_t modsecurity_request_body_end(modsec_rec *msr, char **error_msg) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
} else if (msr->txcfg->reqbody_buffering) {
|
||||
/* No processing if there is no processor and forcing buffering. */
|
||||
return modsecurity_request_body_end_raw(msr, error_msg);
|
||||
}
|
||||
|
||||
/* Note the request body no files length. */
|
||||
|
@ -458,6 +458,7 @@ static void init_msr() {
|
||||
dcfg = (directory_config *)apr_pcalloc(g_mp, sizeof(directory_config));
|
||||
dcfg->is_enabled = 0;
|
||||
dcfg->reqbody_access = 0;
|
||||
dcfg->reqbody_buffering = 0;
|
||||
dcfg->reqbody_inmemory_limit = REQUEST_BODY_DEFAULT_INMEMORY_LIMIT;
|
||||
dcfg->reqbody_limit = REQUEST_BODY_DEFAULT_LIMIT;
|
||||
dcfg->reqbody_no_files_limit = REQUEST_BODY_NO_FILES_DEFAULT_LIMIT;
|
||||
|
@ -713,6 +713,13 @@ static char *msre_action_ctl_validate(msre_engine *engine, msre_action *action)
|
||||
*/
|
||||
return NULL;
|
||||
} else
|
||||
if (strcasecmp(name, "requestBodyBuffering") == 0) {
|
||||
if (parse_boolean(value) == -1) {
|
||||
return apr_psprintf(engine->mp, "Invalid setting for ctl name "
|
||||
" requestBodyBuffering: %s", value);
|
||||
}
|
||||
return NULL;
|
||||
} else
|
||||
if (strcasecmp(name, "responseBodyAccess") == 0) {
|
||||
if (parse_boolean(value) == -1) {
|
||||
return apr_psprintf(engine->mp, "Invalid setting for ctl name "
|
||||
@ -831,6 +838,16 @@ static apr_status_t msre_action_ctl_execute(modsec_rec *msr, apr_pool_t *mptmp,
|
||||
|
||||
return 1;
|
||||
} else
|
||||
if (strcasecmp(name, "requestBodyBuffering") == 0) {
|
||||
int pv = parse_boolean(value);
|
||||
|
||||
if (pv == -1) return -1;
|
||||
msr->txcfg->reqbody_buffering = pv;
|
||||
msr->usercfg->reqbody_buffering = pv;
|
||||
msr_log(msr, 4, "Ctl: Set requestBodyAccess to %d.", pv);
|
||||
|
||||
return 1;
|
||||
} else
|
||||
if (strcasecmp(name, "requestBodyProcessor") == 0) {
|
||||
msr->msc_reqbody_processor = value;
|
||||
msr_log(msr, 4, "Ctl: Set requestBodyProcessor to %s.", value);
|
||||
|
@ -4406,6 +4406,10 @@ SecRule REQUEST_CONTENT_TYPE ^text/xml nolog,pass,<emphasis>ctl:requestBodyProce
|
||||
<para><literal moreinfo="none">requestBodyAccess</literal></para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal moreinfo="none">requestBodyBuffering</literal></para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal moreinfo="none">requestBodyLimit</literal></para>
|
||||
</listitem>
|
||||
@ -4428,7 +4432,8 @@ SecRule REQUEST_CONTENT_TYPE ^text/xml nolog,pass,<emphasis>ctl:requestBodyProce
|
||||
</orderedlist>
|
||||
|
||||
<para>With the exception of<literal moreinfo="none">
|
||||
requestBodyProcessor</literal>, each configuration option corresponds to
|
||||
requestBodyProcessor</literal> and <literal moreinfo="none">
|
||||
requestBodyBuffering</literal>, each configuration option corresponds to
|
||||
one configuration directive and the usage is identical.</para>
|
||||
|
||||
<para>The requestBodyProcessor option allows you to configure the
|
||||
@ -4450,6 +4455,10 @@ SecRule REQUEST_CONTENT_TYPE ^text/xml nolog,pass,<emphasis>ctl:requestBodyProce
|
||||
should be inspected in the <literal
|
||||
moreinfo="none">REQUEST_BODY</literal> phase and an appropriate action
|
||||
taken.</para>
|
||||
|
||||
<para>The requestBodyBuffering option allows you to configure the
|
||||
request body to be buffered (in memory) even if it is not parsed. This
|
||||
allows inspection of REQUEST_BODY even when no parser is used.</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
|
Loading…
x
Reference in New Issue
Block a user