mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-08-14 05:45:59 +03:00
Fix invalid request handling
This commit is contained in:
parent
e1ea8e5fe9
commit
dfbde557ac
@ -192,27 +192,29 @@ apr_status_t read_request_body(modsec_rec *msr, char **error_msg) {
|
|||||||
if (msr->txcfg->debuglog_level >= 4) {
|
if (msr->txcfg->debuglog_level >= 4) {
|
||||||
msr_log(msr, 4, "Input filter: This request does not have a body.");
|
msr_log(msr, 4, "Input filter: This request does not have a body.");
|
||||||
}
|
}
|
||||||
return 0;
|
return APR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msr->txcfg->reqbody_access != 1) {
|
if (msr->txcfg->reqbody_access != 1) {
|
||||||
if (msr->txcfg->debuglog_level >= 4) {
|
if (msr->txcfg->debuglog_level >= 4) {
|
||||||
msr_log(msr, 4, "Input filter: Request body access not enabled.");
|
msr_log(msr, 4, "Input filter: Request body access not enabled.");
|
||||||
}
|
}
|
||||||
return 0;
|
return APR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msr->txcfg->debuglog_level >= 4) {
|
if (msr->txcfg->debuglog_level >= 4) {
|
||||||
msr_log(msr, 4, "Input filter: Reading request body.");
|
msr_log(msr, 4, "Input filter: Reading request body.");
|
||||||
}
|
}
|
||||||
if (modsecurity_request_body_start(msr, error_msg) < 0) {
|
if (modsecurity_request_body_start(msr, error_msg) < 0) {
|
||||||
return -1;
|
return HTTP_INTERNAL_SERVER_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
finished_reading = 0;
|
finished_reading = 0;
|
||||||
msr->if_seen_eos = 0;
|
msr->if_seen_eos = 0;
|
||||||
bb_in = apr_brigade_create(msr->mp, r->connection->bucket_alloc);
|
bb_in = apr_brigade_create(msr->mp, r->connection->bucket_alloc);
|
||||||
if (bb_in == NULL) return -1;
|
if (bb_in == NULL) {
|
||||||
|
return HTTP_INTERNAL_SERVER_ERROR;
|
||||||
|
}
|
||||||
do {
|
do {
|
||||||
apr_status_t rc;
|
apr_status_t rc;
|
||||||
|
|
||||||
@ -222,25 +224,17 @@ apr_status_t read_request_body(modsec_rec *msr, char **error_msg) {
|
|||||||
* too large and APR_EGENERAL when the client disconnects.
|
* too large and APR_EGENERAL when the client disconnects.
|
||||||
*/
|
*/
|
||||||
switch(rc) {
|
switch(rc) {
|
||||||
case APR_INCOMPLETE :
|
|
||||||
*error_msg = apr_psprintf(msr->mp, "Error reading request body: %s", get_apr_error(msr->mp, rc));
|
|
||||||
return -7;
|
|
||||||
case APR_EOF :
|
|
||||||
*error_msg = apr_psprintf(msr->mp, "Error reading request body: %s", get_apr_error(msr->mp, rc));
|
|
||||||
return -6;
|
|
||||||
case APR_TIMEUP :
|
|
||||||
*error_msg = apr_psprintf(msr->mp, "Error reading request body: %s", get_apr_error(msr->mp, rc));
|
|
||||||
return -4;
|
|
||||||
case AP_FILTER_ERROR :
|
case AP_FILTER_ERROR :
|
||||||
*error_msg = apr_psprintf(msr->mp, "Error reading request body: HTTP Error 413 - Request entity too large. (Most likely.)");
|
*error_msg = apr_psprintf(msr->mp, "Error reading request body: HTTP Error 413 - Request entity too large. (Most likely.)");
|
||||||
return -3;
|
break;
|
||||||
case APR_EGENERAL :
|
case APR_EGENERAL :
|
||||||
*error_msg = apr_psprintf(msr->mp, "Error reading request body: Client went away.");
|
*error_msg = apr_psprintf(msr->mp, "Error reading request body: Client went away.");
|
||||||
return -2;
|
break;
|
||||||
default :
|
default :
|
||||||
*error_msg = apr_psprintf(msr->mp, "Error reading request body: %s", get_apr_error(msr->mp, rc));
|
*error_msg = apr_psprintf(msr->mp, "Error reading request body: %s", get_apr_error(msr->mp, rc));
|
||||||
return -1;
|
break;
|
||||||
}
|
}
|
||||||
|
return ap_map_http_request_error(rc, HTTP_BAD_REQUEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Loop through the buckets in the brigade in order
|
/* Loop through the buckets in the brigade in order
|
||||||
@ -256,7 +250,7 @@ apr_status_t read_request_body(modsec_rec *msr, char **error_msg) {
|
|||||||
rc = apr_bucket_read(bucket, &buf, &buflen, APR_BLOCK_READ);
|
rc = apr_bucket_read(bucket, &buf, &buflen, APR_BLOCK_READ);
|
||||||
if (rc != APR_SUCCESS) {
|
if (rc != APR_SUCCESS) {
|
||||||
*error_msg = apr_psprintf(msr->mp, "Failed reading input / bucket (%d): %s", rc, get_apr_error(msr->mp, rc));
|
*error_msg = apr_psprintf(msr->mp, "Failed reading input / bucket (%d): %s", rc, get_apr_error(msr->mp, rc));
|
||||||
return -1;
|
return HTTP_INTERNAL_SERVER_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msr->txcfg->debuglog_level >= 9) {
|
if (msr->txcfg->debuglog_level >= 9) {
|
||||||
@ -269,7 +263,7 @@ apr_status_t read_request_body(modsec_rec *msr, char **error_msg) {
|
|||||||
if((msr->txcfg->is_enabled == MODSEC_ENABLED) && (msr->txcfg->if_limit_action == REQUEST_BODY_LIMIT_ACTION_REJECT)) {
|
if((msr->txcfg->is_enabled == MODSEC_ENABLED) && (msr->txcfg->if_limit_action == REQUEST_BODY_LIMIT_ACTION_REJECT)) {
|
||||||
*error_msg = apr_psprintf(msr->mp, "Request body is larger than the "
|
*error_msg = apr_psprintf(msr->mp, "Request body is larger than the "
|
||||||
"configured limit (%ld).", msr->txcfg->reqbody_limit);
|
"configured limit (%ld).", msr->txcfg->reqbody_limit);
|
||||||
return -5;
|
return HTTP_REQUEST_ENTITY_TOO_LARGE;
|
||||||
} else if((msr->txcfg->is_enabled == MODSEC_ENABLED) && (msr->txcfg->if_limit_action == REQUEST_BODY_LIMIT_ACTION_PARTIAL)) {
|
} else if((msr->txcfg->is_enabled == MODSEC_ENABLED) && (msr->txcfg->if_limit_action == REQUEST_BODY_LIMIT_ACTION_PARTIAL)) {
|
||||||
|
|
||||||
*error_msg = apr_psprintf(msr->mp, "Request body is larger than the "
|
*error_msg = apr_psprintf(msr->mp, "Request body is larger than the "
|
||||||
@ -290,7 +284,7 @@ apr_status_t read_request_body(modsec_rec *msr, char **error_msg) {
|
|||||||
*error_msg = apr_psprintf(msr->mp, "Request body is larger than the "
|
*error_msg = apr_psprintf(msr->mp, "Request body is larger than the "
|
||||||
"configured limit (%ld).", msr->txcfg->reqbody_limit);
|
"configured limit (%ld).", msr->txcfg->reqbody_limit);
|
||||||
|
|
||||||
return -5;
|
return HTTP_REQUEST_ENTITY_TOO_LARGE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -300,7 +294,7 @@ apr_status_t read_request_body(modsec_rec *msr, char **error_msg) {
|
|||||||
modsecurity_request_body_to_stream(msr, buf, buflen, error_msg);
|
modsecurity_request_body_to_stream(msr, buf, buflen, error_msg);
|
||||||
#else
|
#else
|
||||||
if (modsecurity_request_body_to_stream(msr, buf, buflen, error_msg) < 0) {
|
if (modsecurity_request_body_to_stream(msr, buf, buflen, error_msg) < 0) {
|
||||||
return -1;
|
return HTTP_INTERNAL_SERVER_ERROR;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -319,7 +313,7 @@ apr_status_t read_request_body(modsec_rec *msr, char **error_msg) {
|
|||||||
if((msr->txcfg->is_enabled == MODSEC_ENABLED) && (msr->txcfg->if_limit_action == REQUEST_BODY_LIMIT_ACTION_REJECT)) {
|
if((msr->txcfg->is_enabled == MODSEC_ENABLED) && (msr->txcfg->if_limit_action == REQUEST_BODY_LIMIT_ACTION_REJECT)) {
|
||||||
*error_msg = apr_psprintf(msr->mp, "Request body no files data length is larger than the "
|
*error_msg = apr_psprintf(msr->mp, "Request body no files data length is larger than the "
|
||||||
"configured limit (%ld).", msr->txcfg->reqbody_no_files_limit);
|
"configured limit (%ld).", msr->txcfg->reqbody_no_files_limit);
|
||||||
return -5;
|
return HTTP_REQUEST_ENTITY_TOO_LARGE;
|
||||||
} else if ((msr->txcfg->is_enabled == MODSEC_ENABLED) && (msr->txcfg->if_limit_action == REQUEST_BODY_LIMIT_ACTION_PARTIAL)) {
|
} else if ((msr->txcfg->is_enabled == MODSEC_ENABLED) && (msr->txcfg->if_limit_action == REQUEST_BODY_LIMIT_ACTION_PARTIAL)) {
|
||||||
*error_msg = apr_psprintf(msr->mp, "Request body no files data length is larger than the "
|
*error_msg = apr_psprintf(msr->mp, "Request body no files data length is larger than the "
|
||||||
"configured limit (%ld).", msr->txcfg->reqbody_no_files_limit);
|
"configured limit (%ld).", msr->txcfg->reqbody_no_files_limit);
|
||||||
@ -329,12 +323,12 @@ apr_status_t read_request_body(modsec_rec *msr, char **error_msg) {
|
|||||||
} else {
|
} else {
|
||||||
*error_msg = apr_psprintf(msr->mp, "Request body no files data length is larger than the "
|
*error_msg = apr_psprintf(msr->mp, "Request body no files data length is larger than the "
|
||||||
"configured limit (%ld).", msr->txcfg->reqbody_no_files_limit);
|
"configured limit (%ld).", msr->txcfg->reqbody_no_files_limit);
|
||||||
return -5;
|
return HTTP_REQUEST_ENTITY_TOO_LARGE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if((msr->txcfg->is_enabled == MODSEC_ENABLED) && (msr->txcfg->if_limit_action == REQUEST_BODY_LIMIT_ACTION_REJECT))
|
if((msr->txcfg->is_enabled == MODSEC_ENABLED) && (msr->txcfg->if_limit_action == REQUEST_BODY_LIMIT_ACTION_REJECT))
|
||||||
return -1;
|
return HTTP_INTERNAL_SERVER_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -357,7 +351,13 @@ apr_status_t read_request_body(modsec_rec *msr, char **error_msg) {
|
|||||||
|
|
||||||
msr->if_status = IF_STATUS_WANTS_TO_RUN;
|
msr->if_status = IF_STATUS_WANTS_TO_RUN;
|
||||||
|
|
||||||
return rcbe;
|
if (rcbe == -5) {
|
||||||
|
return HTTP_REQUEST_ENTITY_TOO_LARGE;
|
||||||
|
}
|
||||||
|
if (rcbe < 0) {
|
||||||
|
return HTTP_INTERNAL_SERVER_ERROR;
|
||||||
|
}
|
||||||
|
return APR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1032,56 +1032,15 @@ static int hook_request_late(request_rec *r) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
rc = read_request_body(msr, &my_error_msg);
|
rc = read_request_body(msr, &my_error_msg);
|
||||||
if (rc < 0 && msr->txcfg->is_enabled == MODSEC_ENABLED) {
|
if (rc != OK) {
|
||||||
switch(rc) {
|
if (my_error_msg != NULL) {
|
||||||
case -1 :
|
msr_log(msr, 1, "%s", my_error_msg);
|
||||||
if (my_error_msg != NULL) {
|
|
||||||
msr_log(msr, 1, "%s", my_error_msg);
|
|
||||||
}
|
|
||||||
return HTTP_INTERNAL_SERVER_ERROR;
|
|
||||||
break;
|
|
||||||
case -4 : /* Timeout. */
|
|
||||||
if (my_error_msg != NULL) {
|
|
||||||
msr_log(msr, 4, "%s", my_error_msg);
|
|
||||||
}
|
|
||||||
r->connection->keepalive = AP_CONN_CLOSE;
|
|
||||||
return HTTP_REQUEST_TIME_OUT;
|
|
||||||
break;
|
|
||||||
case -5 : /* Request body limit reached. */
|
|
||||||
msr->inbound_error = 1;
|
|
||||||
if((msr->txcfg->is_enabled == MODSEC_ENABLED) && (msr->txcfg->if_limit_action == REQUEST_BODY_LIMIT_ACTION_REJECT)) {
|
|
||||||
r->connection->keepalive = AP_CONN_CLOSE;
|
|
||||||
if (my_error_msg != NULL) {
|
|
||||||
msr_log(msr, 1, "%s. Deny with code (%d)", my_error_msg, HTTP_REQUEST_ENTITY_TOO_LARGE);
|
|
||||||
}
|
|
||||||
return HTTP_REQUEST_ENTITY_TOO_LARGE;
|
|
||||||
} else {
|
|
||||||
if (my_error_msg != NULL) {
|
|
||||||
msr_log(msr, 1, "%s", my_error_msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case -6 : /* EOF when reading request body. */
|
|
||||||
if (my_error_msg != NULL) {
|
|
||||||
msr_log(msr, 4, "%s", my_error_msg);
|
|
||||||
}
|
|
||||||
r->connection->keepalive = AP_CONN_CLOSE;
|
|
||||||
return HTTP_BAD_REQUEST;
|
|
||||||
break;
|
|
||||||
case -7 : /* Partial recieved */
|
|
||||||
if (my_error_msg != NULL) {
|
|
||||||
msr_log(msr, 4, "%s", my_error_msg);
|
|
||||||
}
|
|
||||||
r->connection->keepalive = AP_CONN_CLOSE;
|
|
||||||
return HTTP_BAD_REQUEST;
|
|
||||||
break;
|
|
||||||
default :
|
|
||||||
/* allow through */
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
if (rc == HTTP_REQUEST_ENTITY_TOO_LARGE) {
|
||||||
msr->msc_reqbody_error = 1;
|
msr->inbound_error = 1;
|
||||||
msr->msc_reqbody_error_msg = my_error_msg;
|
}
|
||||||
|
r->connection->keepalive = AP_CONN_CLOSE;
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update the request headers. They might have changed after
|
/* Update the request headers. They might have changed after
|
||||||
|
Loading…
x
Reference in New Issue
Block a user