diff --git a/CHANGES b/CHANGES index 57a8e985..e715676c 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,7 @@ -xx xxx 2007 - 2.1.x -------------------- +15 Oct 2007 - 2.1.4-rc1 +----------------------- + + * Do not process subrequests in phase 2-4. 11 Sep 2007 - 2.1.3 diff --git a/apache2/mod_security2.c b/apache2/mod_security2.c index 32c99777..05185e24 100644 --- a/apache2/mod_security2.c +++ b/apache2/mod_security2.c @@ -52,25 +52,9 @@ int perform_interception(modsec_rec *msr) { msre_actionset *actionset = NULL; const char *message = NULL; const char *phase_text = ""; - const char *intreq_text = ""; - int is_initial_req = ap_is_initial_req(msr->r); int status = DECLINED; int log_level = 1; - /* Check for an initial request */ - - if (is_initial_req != 1) { - if (msr->r->main != NULL) { - intreq_text = "Sub-Request: "; - } - else if (msr->r->prev != NULL) { - intreq_text = "Internal Redirect: "; - } - else { - intreq_text = "Internal Request: "; - } - } - /* Sanity checks first. */ if (msr->was_intercepted == 0) { @@ -93,10 +77,10 @@ int perform_interception(modsec_rec *msr) { * if a nolog action was used or this is not the initial request * to hide the message. */ - log_level = ((actionset->log != 1) || (is_initial_req != 1)) ? 4 : 1; + log_level = (actionset->log != 1) ? 4 : 1; /* Pause the request first (if configured and the initial request). */ - if (actionset->intercept_pause && (is_initial_req == 1)) { + if (actionset->intercept_pause) { msr_log(msr, (log_level > 3 ? log_level : log_level + 1), "Pausing transaction for " "%i msec.", actionset->intercept_pause); /* apr_sleep accepts microseconds */ @@ -108,14 +92,14 @@ int perform_interception(modsec_rec *msr) { case ACTION_DENY : if (actionset->intercept_status != 0) { status = actionset->intercept_status; - message = apr_psprintf(msr->mp, "%sAccess denied with code %i%s.", - intreq_text, status, phase_text); + message = apr_psprintf(msr->mp, "Access denied with code %i%s.", + status, phase_text); } else { log_level = 1; status = HTTP_INTERNAL_SERVER_ERROR; - message = apr_psprintf(msr->mp, "%sAccess denied with code 500%s " + message = apr_psprintf(msr->mp, "Access denied with code 500%s " "(Internal Error: Invalid status code requested %i).", - intreq_text, phase_text, actionset->intercept_status); + phase_text, actionset->intercept_status); } break; @@ -124,25 +108,25 @@ int perform_interception(modsec_rec *msr) { if (ap_find_linked_module("mod_proxy.c") == NULL) { log_level = 1; status = HTTP_INTERNAL_SERVER_ERROR; - message = apr_psprintf(msr->mp, "%sAccess denied with code 500%s " + message = apr_psprintf(msr->mp, "Access denied with code 500%s " "(Configuration Error: Proxy action to %s requested but mod_proxy not found).", - intreq_text, phase_text, + phase_text, log_escape_nq(msr->mp, actionset->intercept_uri)); } else { msr->r->filename = apr_psprintf(msr->mp, "proxy:%s", actionset->intercept_uri); msr->r->proxyreq = PROXYREQ_REVERSE; msr->r->handler = "proxy-server"; status = OK; - message = apr_psprintf(msr->mp, "%sAccess denied using proxy to%s %s.", - intreq_text, phase_text, + message = apr_psprintf(msr->mp, "Access denied using proxy to%s %s.", + phase_text, log_escape_nq(msr->mp, actionset->intercept_uri)); } } else { log_level = 1; status = HTTP_INTERNAL_SERVER_ERROR; - message = apr_psprintf(msr->mp, "%sAccess denied with code 500%s " + message = apr_psprintf(msr->mp, "Access denied with code 500%s " "(Configuration Error: Proxy action requested but it does not work in output phases).", - intreq_text, phase_text); + phase_text); } break; @@ -159,30 +143,30 @@ int perform_interception(modsec_rec *msr) { if (csd) { if (apr_socket_close(csd) == APR_SUCCESS) { status = HTTP_FORBIDDEN; - message = apr_psprintf(msr->mp, "%sAccess denied with connection close%s.", - intreq_text, phase_text); + message = apr_psprintf(msr->mp, "Access denied with connection close%s.", + phase_text); } else { log_level = 1; status = HTTP_INTERNAL_SERVER_ERROR; - message = apr_psprintf(msr->mp, "%sAccess denied with code 500%s " + message = apr_psprintf(msr->mp, "Access denied with code 500%s " "(Error: Connection drop requested but failed to close the " " socket).", - intreq_text, phase_text); + phase_text); } } else { log_level = 1; status = HTTP_INTERNAL_SERVER_ERROR; - message = apr_psprintf(msr->mp, "%sAccess denied with code 500%s " + message = apr_psprintf(msr->mp, "Access denied with code 500%s " "(Error: Connection drop requested but socket not found.", - intreq_text, phase_text); + phase_text); } } #else log_level = 1; status = HTTP_INTERNAL_SERVER_ERROR; - message = apr_psprintf(msr->mp, "%sAccess denied with code 500%s " + message = apr_psprintf(msr->mp, "Access denied with code 500%s " "(Error: Connection drop not implemented on this platform).", - intreq_text, phase_text); + phase_text); #endif break; @@ -195,25 +179,24 @@ int perform_interception(modsec_rec *msr) { } else { status = HTTP_MOVED_TEMPORARILY; } - message = apr_psprintf(msr->mp, "%sAccess denied with redirection to %s using " + message = apr_psprintf(msr->mp, "Access denied with redirection to %s using " "status %i%s.", - intreq_text, log_escape_nq(msr->mp, actionset->intercept_uri), status, phase_text); break; case ACTION_ALLOW : status = DECLINED; - message = apr_psprintf(msr->mp, "%sAccess allowed%s.", intreq_text, phase_text); + message = apr_psprintf(msr->mp, "Access allowed%s.", phase_text); msr->was_intercepted = 0; break; default : log_level = 1; status = HTTP_INTERNAL_SERVER_ERROR; - message = apr_psprintf(msr->mp, "%sAccess denied with code 500%s " + message = apr_psprintf(msr->mp, "Access denied with code 500%s " "(Internal Error: invalid interception action %i).", - intreq_text, phase_text, actionset->intercept_action); + phase_text, actionset->intercept_action); break; } @@ -570,6 +553,13 @@ static int hook_request_late(request_rec *r) { modsec_rec *msr = NULL; int rc; + /* This function needs to run only once per transaction + * (i.e. subrequests and redirects are excluded). + */ + if ((r->main != NULL)||(r->prev != NULL)) { + return DECLINED; + } + /* Find the transaction context and make sure * we are supposed to proceed. */ @@ -583,25 +573,7 @@ static int hook_request_late(request_rec *r) { /* Has this phase been completed already? */ if (msr->phase_request_body_complete) { - /* If we are redirecting and there was no previous response it is - * an error page request and we ignore it. - */ - if ( (msr->r->prev != NULL) - && ((msr->r->prev->headers_out == NULL) || (apr_is_empty_table(msr->r->prev->headers_out))) ) - { - msr_log(msr, 9, "Allowing internally redirected error document: %s", msr->r->uri); - return DECLINED; - } - - if (msr->was_intercepted) { - msr_log(msr, 4, "Phase REQUEST_BODY request already intercepted. Intercepting additional request."); - return perform_interception(msr); - } - - if (msr->txcfg->debuglog_level >= 4) { - msr_log(msr, 4, "Phase REQUEST_BODY already complete, skipping."); - } - + msr_log(msr, 1, "Internal Error: Attempted to process the request body more than once."); return DECLINED; } msr->phase_request_body_complete = 1; @@ -888,6 +860,13 @@ static int hook_log_transaction(request_rec *r) { static void hook_insert_filter(request_rec *r) { modsec_rec *msr = NULL; + /* This function needs to run only once per transaction + * (i.e. subrequests and redirects are excluded). + */ + if ((r->main != NULL)||(r->prev != NULL)) { + return; + } + /* Find the transaction context first. */ msr = retrieve_tx_context(r); if (msr == NULL) return;