mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-09-29 11:16:33 +03:00
Allow ability to force request body buffering to memory. Fixes MODSEC-2.
This commit is contained in:
@@ -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);
|
||||
|
Reference in New Issue
Block a user