From 54fe0b0da0355d1d524c660c7871556a4f3ff897 Mon Sep 17 00:00:00 2001 From: A13501350 <18516149786@163.com> Date: Fri, 14 Aug 2026 17:39:32 +0800 Subject: [PATCH 1/2] fix: record real response status for IIS audit log F part The IIS connector never copied the HTTP response status into the request_rec, so r->status stayed 0 and the audit log rendered the F part as a bogus 'HTTP/1.1 500 Internal Server Error' (ap_get_status_line(0)) for every transaction. Set r->status and r->status_line from the raw HTTP_RESPONSE in OnSendResponse so the logging hook and relevant-status checks use the real response code. --- iis/mymodule.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/iis/mymodule.cpp b/iis/mymodule.cpp index dfaee4b2cb..283d2172f5 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 From 7492907cba06506e4ee983dcae9a8ae6650e5a03 Mon Sep 17 00:00:00 2001 From: A13501350 <18516149786@163.com> Date: Sat, 15 Aug 2026 15:54:26 +0800 Subject: [PATCH 2/2] fix: suppress bogus audit log F-part 500 for IIS internal redirects The IIS connector never copies the response status into the request_rec; r->status is only set in OnSendResponse. A request 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 HTTP/1.1 500 Internal Server Error (ap_get_status_line(0)). Skip audit logging for such transactions unless they were actually intercepted. A blocked request always reaches OnSendResponse with r->status set (403), so it is unaffected. --- apache2/mod_security2.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/apache2/mod_security2.c b/apache2/mod_security2.c index 73e424e59d..ad89a3b190 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)