Subject: [PATCH] apache2: handle AP_FILTER_ERROR in hook_request_late() CVE-2025-54571 is caused by hook_request_late() ignoring an Apache input-filter failure while reading the request body. In ModSecurity 2.9.11, read_request_body() already maps AP_FILTER_ERROR to the internal return code -3 and sets an explanatory error message. However, hook_request_late() only handles negative request-body return codes inside this condition: if (rc < 0 && msr->txcfg->is_enabled == MODSEC_ENABLED) That means rc == -3 is ignored when SecRuleEngine is DetectionOnly. It is also effectively ignored in enforcing mode because the existing switch has no case for -3 and falls through to the default "allow through" path. AP_FILTER_ERROR is not a normal ModSecurity request-body inspection error. It is an Apache input-filter failure and must not be treated like multipart parser errors, request-body limit state, or other ModSecurity-internal conditions that are intentionally reportable in DetectionOnly mode. Continuing after AP_FILTER_ERROR can leave Apache and ModSecurity with inconsistent request/response state, which is the security issue fixed by CVE-2025-54571. This patch keeps the ModSecurity 2.9.11 request-body return-code contract unchanged. Internal ModSecurity request-body errors such as -1, -5, -6 and -7 continue to follow the existing code path, preserving DetectionOnly behavior for uploads and request-body inspection state. Only rc == -3 is handled before the enforcing-mode check. It is logged, marks an inbound error, closes keepalive, and returns HTTP_REQUEST_ENTITY_TOO_LARGE to Apache regardless of SecRuleEngine mode. In short: - AP_FILTER_ERROR / -3 is now fatal in all rule-engine modes. - ModSecurity-internal request-body errors keep the pre-2.9.12 behavior. - DetectionOnly continues to detect and log request-body inspection issues without becoming a blocking mode for normal ModSecurity parser/limit errors. --- diff --git a/apache2/mod_security2.c b/apache2/mod_security2.c --- a/apache2/mod_security2.c +++ b/apache2/mod_security2.c @@ -1032,6 +1032,15 @@ } rc = read_request_body(msr, &my_error_msg); + if (rc == -3) { /* AP_FILTER_ERROR. */ + if (my_error_msg != NULL) { + msr_log(msr, 1, "%s", my_error_msg); + } + msr->inbound_error = 1; + r->connection->keepalive = AP_CONN_CLOSE; + return HTTP_REQUEST_ENTITY_TOO_LARGE; + } + if (rc < 0 && msr->txcfg->is_enabled == MODSEC_ENABLED) { switch(rc) { case -1 :