Impact
An attacker can override the HTTP response’s Content-Type, which could lead to several issues depending on the HTTP scenario. For example, we have demonstrated the potential for XSS and arbitrary script source code disclosure in the latest version of mod_security2.
Patches
Patch is available. All mod_security2 versions need to update.
Workarounds
No known workaround.
References
Issue #2514 mentioned a similar problem.
Details about the issue
We received the report in e-mail ([email protected]), see below:
Impact
An attacker can override the HTTP response’s Content-Type, which could lead to several issues depending on the HTTP scenario. For example, we have demonstrated the potential for XSS and arbitrary script source code disclosure in the latest version of ModSecurity.
Details
This issue was first raised on this GitHub Issue.
#2514
And it was presented by Max Dmitriev at ZeroNights 2021, highlighting the potential security issues. You can check his slides here.
Title: Apache 0day bug, which still nobody knows of, and which was fixed accidentally
Although the slides mention that Apache implemented a blind fix, preventing the original attack from being triggered, the root cause still lies in ModSecurity. In the ap_hook_fixup
phase (hook_request_late
in mod_security2.c
), ModSecurity ignores the AP_FILTER_ERROR
result, allowing the request to continue and causing two HTTP responses.
Moreover, when Apache HTTP Server triggers the AP_FILTER_ERROR
, it places the error message in the brigade
and sets the Content-Type to text/html
. This is also the root cause of the double responses.
The file mod_security2.c
does not handle the case when rc
equals -3
, resulting in the continuation of subsequent processing.
rc = read_request_body(msr, &my_error_msg);
if (rc < 0 && msr->txcfg->is_enabled == MODSEC_ENABLED) {
switch(rc) {
case -1 :
if (my_error_msg != NULL) {
msr_log(msr, 1, "%s", my_error_msg);
}
return HTTP_INTERNAL_SERVER_ERROR;
break;
case -4 : /* Timeout. */
if (my_error_msg != NULL) {
msr_log(msr, 4, "%s", my_error_msg);
}
r->connection->keepalive = AP_CONN_CLOSE;
return HTTP_REQUEST_TIME_OUT;
break;
case -5 : /* Request body limit reached. */
msr->inbound_error = 1;
if((msr->txcfg->is_enabled == MODSEC_ENABLED) && (msr->txcfg->if_limit_action == REQUEST_BODY_LIMIT_ACTION_REJECT)) {
r->connection->keepalive = AP_CONN_CLOSE;
if (my_error_msg != NULL) {
msr_log(msr, 1, "%s. Deny with code (%d)", my_error_msg, HTTP_REQUEST_ENTITY_TOO_LARGE);
}
return HTTP_REQUEST_ENTITY_TOO_LARGE;
} else {
if (my_error_msg != NULL) {
msr_log(msr, 1, "%s", my_error_msg);
}
}
break;
case -6 : /* EOF when reading request body. */
if (my_error_msg != NULL) {
msr_log(msr, 4, "%s", my_error_msg);
}
r->connection->keepalive = AP_CONN_CLOSE;
return HTTP_BAD_REQUEST;
break;
case -7 : /* Partial recieved */
if (my_error_msg != NULL) {
msr_log(msr, 4, "%s", my_error_msg);
}
r->connection->keepalive = AP_CONN_CLOSE;
return HTTP_BAD_REQUEST;
break;
default :
/* allow through */
break;
}
msr->msc_reqbody_error = 1;
msr->msc_reqbody_error_msg = my_error_msg;
}
Therefore, even though the previous attack method has been patched, as long as another path that triggers Apache HTTP Server to return AP_FILTER_ERROR
is found, the same issue can still be reproduced in the latest version of Apache HTTP Server.
How to Fix
I believe the fix should be quite simple. Just add a case to handle -3
in the switch statement above.
PoC
The original PoC triggered the issue by providing an illegal Content-Length
, which has been blind-fixed by Apache HTTP Server in 2020. However, there are still many ways to trigger AP_FILTER_ERROR
. Here is another method to trigger it:
GET /b.php HTTP/1.1
Host: 10.26.0.34
Transfer-Encoding: chunked
Content-Length: 13
-2
AA
0
We successfully reproduced this issue on the Apache HTTP Server by configuring PHP-CGI and enabling the security module with a2enmod security2
!
Additionally, this issue can also be exploited as an XSS vector. When an excessively large POST request is sent to an image file, it triggers the aforementioned bug, causing the image to be processed as text/html
, leading to XSS. If you need an environment to actually trigger the XSS, please let me know and I can provide a Dockerized environment for you!
Credit Discovery To
Orange Tsai (@orange_8361) from DEVCORE Research Team
Impact
An attacker can override the HTTP response’s Content-Type, which could lead to several issues depending on the HTTP scenario. For example, we have demonstrated the potential for XSS and arbitrary script source code disclosure in the latest version of mod_security2.
Patches
Patch is available. All mod_security2 versions need to update.
Workarounds
No known workaround.
References
Issue #2514 mentioned a similar problem.
Details about the issue
We received the report in e-mail ([email protected]), see below:
Impact
An attacker can override the HTTP response’s Content-Type, which could lead to several issues depending on the HTTP scenario. For example, we have demonstrated the potential for XSS and arbitrary script source code disclosure in the latest version of ModSecurity.
Details
This issue was first raised on this GitHub Issue.
And it was presented by Max Dmitriev at ZeroNights 2021, highlighting the potential security issues. You can check his slides here.
Although the slides mention that Apache implemented a blind fix, preventing the original attack from being triggered, the root cause still lies in ModSecurity. In the
ap_hook_fixup
phase (hook_request_late
inmod_security2.c
), ModSecurity ignores theAP_FILTER_ERROR
result, allowing the request to continue and causing two HTTP responses.Moreover, when Apache HTTP Server triggers the
AP_FILTER_ERROR
, it places the error message in thebrigade
and sets the Content-Type totext/html
. This is also the root cause of the double responses.The
file mod_security2.c
does not handle the case whenrc
equals-3
, resulting in the continuation of subsequent processing.Therefore, even though the previous attack method has been patched, as long as another path that triggers Apache HTTP Server to return
AP_FILTER_ERROR
is found, the same issue can still be reproduced in the latest version of Apache HTTP Server.How to Fix
I believe the fix should be quite simple. Just add a case to handle
-3
in the switch statement above.PoC
The original PoC triggered the issue by providing an illegal
Content-Length
, which has been blind-fixed by Apache HTTP Server in 2020. However, there are still many ways to triggerAP_FILTER_ERROR
. Here is another method to trigger it:We successfully reproduced this issue on the Apache HTTP Server by configuring PHP-CGI and enabling the security module with
a2enmod security2
!Additionally, this issue can also be exploited as an XSS vector. When an excessively large POST request is sent to an image file, it triggers the aforementioned bug, causing the image to be processed as
text/html
, leading to XSS. If you need an environment to actually trigger the XSS, please let me know and I can provide a Dockerized environment for you!Credit Discovery To
Orange Tsai (@orange_8361) from DEVCORE Research Team