diff --git a/apache2/mod_security2.c b/apache2/mod_security2.c index 73e424e59..ad89a3b19 100644 --- a/apache2/mod_security2.c +++ b/apache2/mod_security2.c @@ -1276,6 +1276,21 @@ static int hook_log_transaction(request_rec *r) { arr = apr_table_elts(r->headers_out); } +#if defined(VERSION_IIS) + /* The IIS connector never copies the response status into the + * request_rec; r->status is only set in OnSendResponse. A request + * that was superseded by an internal redirect (e.g. the IIS default + * document rewrite of "/" to "/iisstart.htm") never reaches + * OnSendResponse, so its r->status stays 0 and the audit log F part + * would record a bogus "500 Internal Server Error" + * (ap_get_status_line(0)). Skip audit logging for such transactions + * unless they were actually intercepted. + */ + if (r->status == 0 && msr->was_intercepted == 0) { + return DECLINED; + } +#endif + msr->r = r; msr->response_status = r->status; msr->status_line = ((r->status_line != NULL) diff --git a/iis/mymodule.cpp b/iis/mymodule.cpp index dfaee4b2c..283d2172f 100644 --- a/iis/mymodule.cpp +++ b/iis/mymodule.cpp @@ -450,6 +450,22 @@ CMyHttpModule::OnSendResponse( pHttpResponse = pHttpContext->GetResponse(); pRawHttpResponse = pHttpResponse->GetRawHttpResponse(); + // here we must transfer response status + // otherwise r->status stays 0 and the audit log records a + // bogus "500 Internal Server Error" (ap_get_status_line(0)) + // for every transaction + // + if(pRawHttpResponse->StatusCode > 0) + { + r->status = pRawHttpResponse->StatusCode; + + if(pRawHttpResponse->pReason != NULL && pRawHttpResponse->ReasonLength > 0) + { + r->status_line = apr_psprintf(r->pool, "%d %s", r->status, + ZeroTerminate(pRawHttpResponse->pReason, pRawHttpResponse->ReasonLength, r->pool)); + } + } + // here we must add handling of chunked response // apparently IIS 7 calls this handler once per chunk // see: http://stackoverflow.com/questions/4385249/how-to-buffer-and-process-chunked-data-before-sending-headers-in-iis7-native-mod