diff --git a/apache2/apache2_io.c b/apache2/apache2_io.c index f4df75ed..94503327 100644 --- a/apache2/apache2_io.c +++ b/apache2/apache2_io.c @@ -510,10 +510,13 @@ apr_status_t output_filter(ap_filter_t *f, apr_bucket_brigade *bb_in) { ap_remove_output_filter(f); return send_error_bucket(msr, f, HTTP_INTERNAL_SERVER_ERROR); } + if (rc > 0) { /* transaction needs to be interrupted */ int status = perform_interception(msr); if (status != DECLINED) { /* DECLINED means we allow-ed the request. */ ap_remove_output_filter(f); + msr->of_status = OF_STATUS_COMPLETE; + msr->of_status = RESBODY_STATUS_ERROR; return send_error_bucket(msr, f, status); } } diff --git a/apache2/mod_security2.c b/apache2/mod_security2.c index c94f03e9..903884c3 100644 --- a/apache2/mod_security2.c +++ b/apache2/mod_security2.c @@ -919,7 +919,8 @@ static void hook_insert_filter(request_rec *r) { /* Add the input filter, but only if we need it to run. */ if (msr->if_status == IF_STATUS_WANTS_TO_RUN) { if (msr->txcfg->debuglog_level >= 4) { - msr_log(msr, 4, "Hook insert_filter: Adding input forwarding filter %s(r %pp).", (((r->main != NULL)||(r->prev != NULL)) ? "for subrequest " : ""), r); + msr_log(msr, 4, "Hook insert_filter: Adding input forwarding filter %s(r %pp).", + (((r->main != NULL)||(r->prev != NULL)) ? "for subrequest " : ""), r); } ap_add_input_filter("MODSECURITY_IN", msr, r, r->connection); @@ -961,7 +962,6 @@ static void hook_insert_filter(request_rec *r) { } } -/* NOTE: This is causing and endless loop when blocking in phase:3 */ /** * Invoked whenever Apache starts processing an error. A chance * to insert ourselves into the output filter chain. @@ -975,16 +975,6 @@ static void hook_insert_error_filter(request_rec *r) { msr = retrieve_tx_context(r); if (msr == NULL) return; - /* Do not run if we are already running, which may happen - * if we intercept in phase 3. - */ - if (msr->of_is_error == 1) { - if (msr->txcfg->debuglog_level >= 4) { - msr_log(msr, 4, "Hook insert_error_filter: Already processing."); - } - return; - } - /* Do not run if not enabled. */ if (msr->txcfg->is_enabled == 0) { if (msr->txcfg->debuglog_level >= 4) { diff --git a/apache2/modsecurity.c b/apache2/modsecurity.c index 81abecab..2485e36a 100644 --- a/apache2/modsecurity.c +++ b/apache2/modsecurity.c @@ -494,7 +494,20 @@ static apr_status_t modsecurity_process_phase_logging(modsec_rec *msr) { * need to be explicitly provided since it's already available * in the modsec_rec structure. */ -apr_status_t modsecurity_process_phase(modsec_rec *msr, int phase) { +apr_status_t modsecurity_process_phase(modsec_rec *msr, unsigned int phase) { + /* Check if we've should run. */ + if (msr->was_intercepted) { + msr_log(msr, 4, "Skipping phase %i as request was already intercepted.", phase); + return 0; + } + + /* Do not process the same phase twice. */ + if (msr->phase >= phase) { + msr_log(msr, 4, "Skipping phase %i because it was previously run (at %i now).", + phase, msr->phase); + return 0; + } + msr->phase = phase; switch(phase) { diff --git a/apache2/modsecurity.h b/apache2/modsecurity.h index 343a5364..15fd2866 100644 --- a/apache2/modsecurity.h +++ b/apache2/modsecurity.h @@ -540,7 +540,7 @@ void DSOLOCAL modsecurity_shutdown(msc_engine *msce); apr_status_t DSOLOCAL modsecurity_tx_init(modsec_rec *msr); -apr_status_t DSOLOCAL modsecurity_process_phase(modsec_rec *msr, int phase); +apr_status_t DSOLOCAL modsecurity_process_phase(modsec_rec *msr, unsigned int phase); /* Request body functions */