Skip to content

Apache httpd does not execute ErrorDocument directive if response code is changed during phase 4 #2849

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
TomasKorbar opened this issue Dec 22, 2022 · 0 comments
Labels
2.x Related to ModSecurity version 2.x bug It is a confirmed bug Platform - Apache

Comments

@TomasKorbar
Copy link

Describe the bug
When response code is changed during phase 4 and the original response code is other than 200, Apache httpd does not execute ErrorDocument directive and bad response is generated.

Logs and dumps

Output of:

  1. DebugLogs (level 9)

modsec_debug.log

  1. AuditLogs

modsec_audit.log

  1. Error logs

error_log.txt

To Reproduce

  1. Add following configuration:
    ProxyPass /helloworld http://localhost:9090/unavaible
    ErrorDocument 403 /custompage.html
    SecRule RESPONSE_PROTOCOL "@contains HTTP" "id:'4',phase:4,auditlog,log,deny,status:403,msg:'yay!'"
  1. Create and place custompage.html page to server root.
  2. execute $ curl -v localhost/helloworld

Actual behavior

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access this resource.</p>
<p>Additionally, a 503 Service Unavailable
error was encountered while trying to use an ErrorDocument to handle the request.</p>
</body></html>

Expected behavior
Proper rewritten response with custom error document:

Server (please complete the following information):

  • ModSecurity version (and connector): mod_security-2.9.6
  • WebServer: httpd-2.4.37
  • OS (and distro): Linux Fedora

Rule Set (please complete the following information):

  • Running any public or commercial rule set? No

Additional context

In my opinion, this is caused by apache httpds assumption that changed status of request which got through filter is a recursive error which occured during handling of previous errors.
See ap_die_r function in http module of apache, particularly this part of code:

    /*
     * The following takes care of Apache redirects to custom response URLs
     * Note that if we are already dealing with the response to some other
     * error condition, we just report on the original error, and give up on
     * any attempt to handle the other thing "intelligently"...
     */
    if (recursive_error != HTTP_OK) {
        while (r_1st_err->prev && (r_1st_err->prev->status != HTTP_OK))
            r_1st_err = r_1st_err->prev;  /* Get back to original error */

        if (r_1st_err != r) {
            /* The recursive error was caused by an ErrorDocument specifying
             * an internal redirect to a bad URI.  ap_internal_redirect has
             * changed the filter chains to point to the ErrorDocument's
             * request_rec.  Back out those changes so we can safely use the
             * original failing request_rec to send the canned error message.
             *
             * ap_send_error_response gets rid of existing resource filters
             * on the output side, so we can skip those.
             */
            update_r_in_filters(r_1st_err->proto_output_filters, r, r_1st_err);
            update_r_in_filters(r_1st_err->input_filters, r, r_1st_err);
        }

        custom_response = NULL; /* Do NOT retry the custom thing! */
    }
    else {
        int error_index = ap_index_of_response(type);
        custom_response = ap_response_code_string(r, error_index);
        recursive_error = 0;
    }

Clearing the original response code with f->r->status = 200; in send_error_bucket function appears to fix this issue.

This issue is a continuation of #533 and extends findings of Marc Stern in #533 (comment)

TomasKorbar added a commit to TomasKorbar/ModSecurity that referenced this issue Dec 22, 2022
If this is left intact, then apache thinks that this code
was generated during processing of ErrorDocument and does not
handle it properly

Fix owasp-modsecurity#2849
@marcstern marcstern added Platform - Apache 2.x Related to ModSecurity version 2.x bug It is a confirmed bug labels Jan 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2.x Related to ModSecurity version 2.x bug It is a confirmed bug Platform - Apache
Projects
None yet
Development

No branches or pull requests

2 participants