Wicket
  1. Wicket
  2. WICKET-4196

Accessing Wicket through AJP makes Wicket vulnerable to HTTP Response Splitting Attack

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Won't Fix
    • Affects Version/s: 1.4.19
    • Fix Version/s: None
    • Component/s: wicket
    • Labels:
    • Environment:
      CentOS 5.6, Apache HTTPD 2.2.3 with mod_jk 1.2.31 and Apache Tomcat 6

      Description

      Hello all,

      When having a Wicket application installed on Tomcat and you call that application through HTTP, Wicket is protected against HTTP Response Splitting. However, when you call Tomcat through AJP (for example through an apache httpd proxy), HTTP Response Splitting becomes possible.

      To demonstrate, I created a simple application and called it through an AJP proxy with the curl command:

      curl -max-redirs 0 -Dfoo 'http:///myapp/home?wicket:bookmarkablePage=:org.apache.wicket.markup.html.pages.BrowserInfoPage&cto=Foobar%3f%0d%0aEvilHeader:%20SPLIT%2f%0d%0aAnotherEvilHeader:%20HEADER'

      Note the '%0d%0a', a CRLF in the request. When calling Wicket through Tomcat, these are replaced by spaces, but when calling Wicket through AJP, these are left intact, getting us the following response:

      HTTP/1.1 302 Moved Temporarily
      Date: Wed, 02 Nov 2011 14:34:32 GMT
      Server: Apache
      Set-Cookie: JSESSIONID=4F403B53D091B40F6C3FBC2321A2E348.pub-app04; Path=/myapp; HttpOnly Location: http://<ip-address>/myapp/Foobar;jsessionid=4F403B53D091B40F6C3FBC2321A2E348.pub-app04?
      EvilHeader: SPLIT/-
      AnotherEvilHeader: HEADER
      Content-Length: 0
      Connection: close
      Content-Type: text/plain; charset=UTF-8

      Here we have 2 Evil Headers, that could be inserted by hackers by adding %0d%0a to the get-request.

      The problem is that a hacker can now post URL's that look like they're going to your site on some forum or in an email. But when the user actually clicks on the link, a custom header could redirect the user to a malicious site. In the example, I used "EvilHeader", but it could be any header, like an HTTP 301 redirect. Basically, the hacker can include any header he wants in the response that the user is going to get when he clicks on the link.

      Note we are not vulnerable if you connect directly to tomcat with HTTP - it appears that the Coyote HTTP Connector is sanitising the HTTP headers and replacing the CRLF with two spaces. You have to connect via Apache and AJP to reproduce.

      For a more detailed description of HTTP Response Splitting (which is on the OWASP list of security vulnerabilities), you can check:

      https://www.owasp.org/index.php/HTTP_Response_Splitting
      http://www.acunetix.com/vulnerabilities/CRLF-injectionHTTP-respon.htm
      http://packetstormsecurity.org/papers/general/whitepaper_httpresponse.pdf
      http://www.infosecwriters.com/text_resources/pdf/HTTP_Response.pdf

        Activity

        Hide
        Martin Grigorov added a comment -

        The changes are reverted.

        Summary:
        the recommended way is to use Servlet Filter or HttpServletResponseWrapper that disallows any bad header values.
        Tomcat is improved in its latest versions.

        Show
        Martin Grigorov added a comment - The changes are reverted. Summary: the recommended way is to use Servlet Filter or HttpServletResponseWrapper that disallows any bad header values. Tomcat is improved in its latest versions.
        Hide
        Martin Grigorov added a comment -

        Here are the fixes in Tomcat:

        Tomcat trunk:

        http://svn.apache.org/viewvc?rev=1201069&view=rev
        http://svn.apache.org/viewvc?rev=1201087&view=rev (only whitespace)

        TC 7 backport:

        http://svn.apache.org/viewvc?rev=1201076&view=rev
        http://svn.apache.org/viewvc?rev=1201088&view=rev

        TC 6 backport plus fix for old impl that's no longer present in TC 7+:

        http://svn.apache.org/viewvc?rev=1201452&view=rev

        TC 5.5 backport

        http://svn.apache.org/viewvc?rev=1221050&view=rev

        First "fixed" releases:

        Tomcat 7.0.23
        Tomcat 6.0.35
        Tomcat 5.5.35 (not yet released but currently under release vote)

        I'll revert the improvements in Wicket code (1.5/6.0).

        Show
        Martin Grigorov added a comment - Here are the fixes in Tomcat: Tomcat trunk: http://svn.apache.org/viewvc?rev=1201069&view=rev http://svn.apache.org/viewvc?rev=1201087&view=rev (only whitespace) TC 7 backport: http://svn.apache.org/viewvc?rev=1201076&view=rev http://svn.apache.org/viewvc?rev=1201088&view=rev TC 6 backport plus fix for old impl that's no longer present in TC 7+: http://svn.apache.org/viewvc?rev=1201452&view=rev TC 5.5 backport http://svn.apache.org/viewvc?rev=1221050&view=rev First "fixed" releases: Tomcat 7.0.23 Tomcat 6.0.35 Tomcat 5.5.35 (not yet released but currently under release vote) I'll revert the improvements in Wicket code (1.5/6.0).
        Hide
        Martin Grigorov added a comment -

        This ticket contains commits which are in to-be-released 1.5.4 version.

        I have information that the reporter uses a custom servlet filter to solve the problem in his application (we think this is the best option - a shared/OSS filter that can protect against this attack for all web servers and frameworks).
        Also I have information that AJP is improved in its latest version. It is too late to revert my changes for 1.5.4 but after confirmation from Tomcat developers I'll revert it for 1.5.5/6.0.

        Show
        Martin Grigorov added a comment - This ticket contains commits which are in to-be-released 1.5.4 version. I have information that the reporter uses a custom servlet filter to solve the problem in his application (we think this is the best option - a shared/OSS filter that can protect against this attack for all web servers and frameworks). Also I have information that AJP is improved in its latest version. It is too late to revert my changes for 1.5.4 but after confirmation from Tomcat developers I'll revert it for 1.5.5/6.0.
        Hide
        Olivier Jaquemet added a comment -

        Duplicating this behavior is not on your control, your either developp the webapp or the container, rarely both. Therefore you must ensure security of your own development, and this will probably be done on both side whether or no you know it. And I would expect the app server to provide such basic security feature, like I expect application to follow security best practice.

        Regarding the servletfilter to filter response content, this is an approach available in the OWASP ESAPI library with its SecurityWrapperReponse :
        https://www.owasp.org/index.php/Category:OWASP_Enterprise_Security_API

        Though output filtering is not enough, and I would strongly recommend proper filtering of input, not using a filter, but with a real semantic validation of parameter for each use case (eg \n\r are authorized for an article submitted thourhg textearea, not for a price submitted in a textfield)

        Show
        Olivier Jaquemet added a comment - Duplicating this behavior is not on your control, your either developp the webapp or the container, rarely both. Therefore you must ensure security of your own development, and this will probably be done on both side whether or no you know it. And I would expect the app server to provide such basic security feature, like I expect application to follow security best practice. Regarding the servletfilter to filter response content, this is an approach available in the OWASP ESAPI library with its SecurityWrapperReponse : https://www.owasp.org/index.php/Category:OWASP_Enterprise_Security_API Though output filtering is not enough, and I would strongly recommend proper filtering of input, not using a filter, but with a real semantic validation of parameter for each use case (eg \n\r are authorized for an article submitted thourhg textearea, not for a price submitted in a textfield)
        Hide
        Martin Grigorov added a comment -

        I think Igor's idea of a custom Servlet Filter to do this is the best approach.
        Duplicating this logic in the web container, the web framework and the application is error prone.

        Show
        Martin Grigorov added a comment - I think Igor's idea of a custom Servlet Filter to do this is the best approach. Duplicating this logic in the web container, the web framework and the application is error prone.
        Hide
        Olivier Jaquemet added a comment -

        @Konstantin : As I already said, I do agree that validation must be performed by the webapp on untrusted data prior to using/sending it. BUT if Tomcat AJP was behaving as his HTTP/1.1 counterpart, this would be a best effort to improve security of webapps which may not have though of all security aspects. Because unfortunately we don't live in a child's fantasy world and all webapp are not properly coded. My two cents.

        Show
        Olivier Jaquemet added a comment - @Konstantin : As I already said, I do agree that validation must be performed by the webapp on untrusted data prior to using/sending it. BUT if Tomcat AJP was behaving as his HTTP/1.1 counterpart, this would be a best effort to improve security of webapps which may not have though of all security aspects. Because unfortunately we don't live in a child's fantasy world and all webapp are not properly coded. My two cents.
        Hide
        Konstantin Kolinko added a comment -

        @Olivier:
        > specially with regards to Tomcat, there is a non homegenous behavior of ajp vs http

        The '\n' handling in HTTP connector is mostly legacy code. It is not enough to protect from all known scenarios. When the header is being sent out it is nearly too late to fix anything.

        Show
        Konstantin Kolinko added a comment - @Olivier: > specially with regards to Tomcat, there is a non homegenous behavior of ajp vs http The '\n' handling in HTTP connector is mostly legacy code. It is not enough to protect from all known scenarios. When the header is being sent out it is nearly too late to fix anything.
        Hide
        Olivier Jaquemet added a comment -

        As far as I am concerned, I would expect a fix on both side :
        1. On the container side, specially when observing the invalid behavior of the AJP/1.3 connector as opposed to the HTTP/1.1 connector which is correct,
        2. On the webapp side, whether it is Wicket or any other webapp, but moreover for Wicket as it is a web framework

        As I said earlier, I do not use Wicket at all, but I encountered exactly the same problem at the same time with my webapp. I will provide a fix in my webapp. But I also expect a fix by the Tomcat team.

        @Konstantin : I completely agree with your approach on security : the webapp is responsible for validation of parameter and for the data being sent to the user HTTP/HTML or any other channel. And as you said the Doc/RFC clearly states how headers should be encoded. But when it comes to security, RFC are secondary to the common usage scenario. And specially with regards to Tomcat, there is a non homegenous behavior of ajp vs http. Also I am pretty sure I could investigate the issue and reproduce the bug with other native headers...

        Show
        Olivier Jaquemet added a comment - As far as I am concerned, I would expect a fix on both side : 1. On the container side, specially when observing the invalid behavior of the AJP/1.3 connector as opposed to the HTTP/1.1 connector which is correct, 2. On the webapp side, whether it is Wicket or any other webapp, but moreover for Wicket as it is a web framework As I said earlier, I do not use Wicket at all, but I encountered exactly the same problem at the same time with my webapp. I will provide a fix in my webapp. But I also expect a fix by the Tomcat team. @Konstantin : I completely agree with your approach on security : the webapp is responsible for validation of parameter and for the data being sent to the user HTTP/HTML or any other channel. And as you said the Doc/RFC clearly states how headers should be encoded. But when it comes to security, RFC are secondary to the common usage scenario. And specially with regards to Tomcat, there is a non homegenous behavior of ajp vs http. Also I am pretty sure I could investigate the issue and reproduce the bug with other native headers...
        Hide
        Igor Vaynberg added a comment -

        hrm. i think im changing my mind on whether or not we, as a web framework, should be attempting to fix this.

        a wicket application is not always composed of just the wicket filter, a great number of them use other filters and servlets - thus we cant truly say that your wicket application is safe from this kind of attack because other filters and servlets in the application are not safe.

        i think we should drop this and let container folks fix it, which is the only place where something like this can be fixed.

        alternatively someone can release a servlet filter that can sit infront of everything else and look for this kind of thing...

        Show
        Igor Vaynberg added a comment - hrm. i think im changing my mind on whether or not we, as a web framework, should be attempting to fix this. a wicket application is not always composed of just the wicket filter, a great number of them use other filters and servlets - thus we cant truly say that your wicket application is safe from this kind of attack because other filters and servlets in the application are not safe. i think we should drop this and let container folks fix it, which is the only place where something like this can be fixed. alternatively someone can release a servlet filter that can sit infront of everything else and look for this kind of thing...
        Hide
        Konstantin Kolinko added a comment -

        > The question is whether every application/framework should do that
        > or the web container should sanitize the headers ?

        Only those that allow user-provided data in headers. In general headers with user-provided data are rare.

        > Wicket now also replaces \n and \r with ' '

        That is not enough. If you allow any Unicode String as a parameter, there might be other chars that should not be allowed in the header.

        There was similar issue with Reason phrase in HTTP response - see CVE-2008-1232, but while it is clear how to sanitize a reason phrase - it is replaced with default one, it is not clear what to do with headers.

        My personal though is that it is better to check and reject invalid header names and values with IllegalArgumentException in setHeader()/addHeader() call, but Servlet API is more in favor of silently dropping them.

        > Tomcat when used thru AJP connector doesn't behave as thru HTTP connector

        There are several versions of HTTP and of AJP connectors. Some behave different than others.

        Show
        Konstantin Kolinko added a comment - > The question is whether every application/framework should do that > or the web container should sanitize the headers ? Only those that allow user-provided data in headers. In general headers with user-provided data are rare. > Wicket now also replaces \n and \r with ' ' That is not enough. If you allow any Unicode String as a parameter, there might be other chars that should not be allowed in the header. There was similar issue with Reason phrase in HTTP response - see CVE-2008-1232, but while it is clear how to sanitize a reason phrase - it is replaced with default one, it is not clear what to do with headers. My personal though is that it is better to check and reject invalid header names and values with IllegalArgumentException in setHeader()/addHeader() call, but Servlet API is more in favor of silently dropping them. > Tomcat when used thru AJP connector doesn't behave as thru HTTP connector There are several versions of HTTP and of AJP connectors. Some behave different than others.
        Hide
        Martin Grigorov added a comment -

        Hi Konstantin,

        Thanks for your comment!

        The question is whether every application/framework should do that or the web container should sanitize the headers ?

        Wicket now also replaces \n and \r with ' ' as Tomcat does but not only for the value but also for the header names.
        Also Tomcat when used thru AJP connector doesn't behave as thru HTTP connector. I guess Olivier already created a ticket in Tomcat's issue tracker ?

        Show
        Martin Grigorov added a comment - Hi Konstantin, Thanks for your comment! The question is whether every application/framework should do that or the web container should sanitize the headers ? Wicket now also replaces \n and \r with ' ' as Tomcat does but not only for the value but also for the header names. Also Tomcat when used thru AJP connector doesn't behave as thru HTTP connector. I guess Olivier already created a ticket in Tomcat's issue tracker ?
        Hide
        Konstantin Kolinko added a comment -

        > String foo = request.getParameter("foo");
        > if (foo != null)

        { > response.addHeader("Foo", foo); > }

        In general it is wrong to call addHeader() with arbitrary data provided by client. Applications should sanitize their headers, like they have to sanitize (xml-encode) the same parameter values when printing them in HTML response.

        As Javadoc for addHeader()/setHeader() says in the Servlet specification, the header values "should be encoded according to RFC 2047".

        It was discussed in public several times. There is no sane way to reject a header.

        Show
        Konstantin Kolinko added a comment - > String foo = request.getParameter("foo"); > if (foo != null) { > response.addHeader("Foo", foo); > } In general it is wrong to call addHeader() with arbitrary data provided by client. Applications should sanitize their headers, like they have to sanitize (xml-encode) the same parameter values when printing them in HTML response. As Javadoc for addHeader()/setHeader() says in the Servlet specification, the header values "should be encoded according to RFC 2047". It was discussed in public several times. There is no sane way to reject a header.
        Hide
        Olivier Jaquemet added a comment -

        I am in the process of submitting a security bug report to the tomcat team, but could you change the visibility of this issue so nobody sees it until a fix is available ?

        This is in order to comply with the following Apache recommendation :
        > We strongly encourage folks to report such problems to our private security mailing list first, before disclosing them in a public forum.

        Show
        Olivier Jaquemet added a comment - I am in the process of submitting a security bug report to the tomcat team, but could you change the visibility of this issue so nobody sees it until a fix is available ? This is in order to comply with the following Apache recommendation : > We strongly encourage folks to report such problems to our private security mailing list first, before disclosing them in a public forum.
        Hide
        Gert-Jan Schouten added a comment -

        We were using Tomcat 6.0.33 when we found this issue. Thanks for all comments!

        Show
        Gert-Jan Schouten added a comment - We were using Tomcat 6.0.33 when we found this issue. Thanks for all comments!
        Hide
        Martin Grigorov added a comment -

        Yes, I also reproduced it locally.
        I just improved Wicket 1.5 to sanitize web response's headers.
        The improvement will be soon ported to 1.4 as well.
        Thank you for your comments here!

        Show
        Martin Grigorov added a comment - Yes, I also reproduced it locally. I just improved Wicket 1.5 to sanitize web response's headers. The improvement will be soon ported to 1.4 as well. Thank you for your comments here!
        Hide
        Olivier Jaquemet added a comment -

        I needed to diagnose exactly the same problem with another application, totally unrelated to WICKET, here is my first returns on this subjects.

        I could reproduce the HTTP Splitting vulnerability with the latest version of HTTPD, mod_jk, and Tomcat :
        Apache/2.2.21 (Win32) mod_jk/1.2.32, Tomcat 6.0.33
        The vulnerability does not appears when using only Tomcat 6.0.33.

        To reproduce :
        1. Drop this JSP in the default ROOT webapp of tomcat

        <%
        
        // Test me by invoking this JSP like this : 
        // http://www.example.com/header.jsp?foo=bar%0D%0AContent-Length:%20100%0D%0A%0D%0Apoisoned
        
        String foo = request.getParameter("foo");
        if (foo != null) {
          response.addHeader("Foo", foo);
        }
        
        %>
        This is the expected content of the file, nothing should appear above this line.
        

        2. Configure Apache Tomcat with both an HTTP/1.1 connector and AJP/1.3 connector
        This is the default when downloading Tomcat 6.0.33, you should have nothing to do.

        3. Configure Apache HTTPD with mod_jk

        • Download mod_jk 1.2.32 binaries and drop mod_jk.so in modules directory
        • Add the following worker.properties in conf directory :
          worker.list=tomcat1
          worker.tomcat1.port=8009 
          worker.tomcat1.host=127.0.0.1
          worker.tomcat1.type=ajp13 
          
        • Update httpd.conf with the following line at the end :
           LoadModule jk_module modules/mod_jk.so
           JkWorkersFile conf/workers.properties
           JkLogFile logs/mod_jk.log
           JkLogLevel info
           JkShmFile logs/shm
           JkMount /* tomcat1 
          

        3. Access header.jsp through the HTTP/1.1 connector of tomcat with this URL :
        http://127.0.0.1:8080/header.jsp?foo=bar%0D%0AContent-Length:%2010%0D%0A%0D%0Apoisoned
        The response content is as expected : "This is the expected content of the file, nothing should appear above this line."

        4. Access header.sjp through Apache, with this URL :
        http://127.0.0.1:80/header.jsp?foo=bar%0D%0AContent-Length:%2010%0D%0A%0D%0Apoisoned
        The response content has been modified and contains new header and the content has been truncated.

        I will now report this security issue to Apache/mod_jk

        Show
        Olivier Jaquemet added a comment - I needed to diagnose exactly the same problem with another application, totally unrelated to WICKET, here is my first returns on this subjects. I could reproduce the HTTP Splitting vulnerability with the latest version of HTTPD, mod_jk, and Tomcat : Apache/2.2.21 (Win32) mod_jk/1.2.32, Tomcat 6.0.33 The vulnerability does not appears when using only Tomcat 6.0.33. To reproduce : 1. Drop this JSP in the default ROOT webapp of tomcat <% // Test me by invoking this JSP like this : // http://www.example.com/header.jsp?foo=bar%0D%0AContent-Length:%20100%0D%0A%0D%0Apoisoned String foo = request.getParameter("foo"); if (foo != null) { response.addHeader("Foo", foo); } %> This is the expected content of the file, nothing should appear above this line. 2. Configure Apache Tomcat with both an HTTP/1.1 connector and AJP/1.3 connector This is the default when downloading Tomcat 6.0.33, you should have nothing to do. 3. Configure Apache HTTPD with mod_jk Download mod_jk 1.2.32 binaries and drop mod_jk.so in modules directory Add the following worker.properties in conf directory : worker.list=tomcat1 worker.tomcat1.port=8009 worker.tomcat1.host=127.0.0.1 worker.tomcat1.type=ajp13 Update httpd.conf with the following line at the end : LoadModule jk_module modules/mod_jk.so JkWorkersFile conf/workers.properties JkLogFile logs/mod_jk.log JkLogLevel info JkShmFile logs/shm JkMount /* tomcat1 3. Access header.jsp through the HTTP/1.1 connector of tomcat with this URL : http://127.0.0.1:8080/header.jsp?foo=bar%0D%0AContent-Length:%2010%0D%0A%0D%0Apoisoned The response content is as expected : "This is the expected content of the file, nothing should appear above this line." 4. Access header.sjp through Apache, with this URL : http://127.0.0.1:80/header.jsp?foo=bar%0D%0AContent-Length:%2010%0D%0A%0D%0Apoisoned The response content has been modified and contains new header and the content has been truncated. I will now report this security issue to Apache/mod_jk
        Hide
        Olivier Jaquemet added a comment -

        As far as i known, HTTP response splitting attack are usually fixed at response time. By filtering each header for \n & \r

        You might be interested in having a look at the following vulnerability of Tomcat :
        http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2008-1232

        It is stated that it's a XSS vulnerability, but I would also qualify this vulnerability as an HTTP response splitting vulnerability.
        Indeed the fix clearly adds the removal of \n and \r when sending headers :
        http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/InternalOutputBuffer.java?r1=505604&r2=673834&pathrev=673834

        It has been fix in Tomcat 6.0.18. And because the bug reporter of this current issue only specified Tomcat 6. Might be worth a look

        PS : I do not use wicket, nor know the context of your bug report, but your issue came as a google result when searching for http splitting attack, and I add found the tomcat bug prior to reading your issue. So if it can help in any way...

        Show
        Olivier Jaquemet added a comment - As far as i known, HTTP response splitting attack are usually fixed at response time. By filtering each header for \n & \r You might be interested in having a look at the following vulnerability of Tomcat : http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2008-1232 It is stated that it's a XSS vulnerability, but I would also qualify this vulnerability as an HTTP response splitting vulnerability. Indeed the fix clearly adds the removal of \n and \r when sending headers : http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/InternalOutputBuffer.java?r1=505604&r2=673834&pathrev=673834 It has been fix in Tomcat 6.0.18. And because the bug reporter of this current issue only specified Tomcat 6. Might be worth a look PS : I do not use wicket, nor know the context of your bug report, but your issue came as a google result when searching for http splitting attack, and I add found the tomcat bug prior to reading your issue. So if it can help in any way...
        Hide
        Martin Grigorov added a comment -

        I think neither Wicket nor Tomcat/anyWebContainer should blindly disallow %0D%0A in the request parameters. If those characters are not allowed then a FORM with method GET and a textarea inside wont be able to work.

        Show
        Martin Grigorov added a comment - I think neither Wicket nor Tomcat/anyWebContainer should blindly disallow %0D%0A in the request parameters. If those characters are not allowed then a FORM with method GET and a textarea inside wont be able to work.
        Hide
        Martin Grigorov added a comment -

        The problem in BrowserInfoPage is fixed with r1199263 in 1.4.x.

        Show
        Martin Grigorov added a comment - The problem in BrowserInfoPage is fixed with r1199263 in 1.4.x.
        Hide
        Martin Grigorov added a comment -

        Wicket 1.5 is no affected because it doesn't use request parameters ('cto') but uses org.apache.wicket.RestartResponseAtInterceptPageException.InterceptData to keep the original url.

        Show
        Martin Grigorov added a comment - Wicket 1.5 is no affected because it doesn't use request parameters ('cto') but uses org.apache.wicket.RestartResponseAtInterceptPageException.InterceptData to keep the original url.
        Hide
        Martin Grigorov added a comment -

        The problem is related to BrowserInfoPage's cto (continueTo) parameter.
        To avoid such problems use org.apache.wicket.settings.ISecuritySettings.setEnforceMounts(true). This will disable wicket:bookmarkablePage functionality and no one will be able to reach that page.
        Prio: Critical -> Major.

        Show
        Martin Grigorov added a comment - The problem is related to BrowserInfoPage's cto (continueTo) parameter. To avoid such problems use org.apache.wicket.settings.ISecuritySettings.setEnforceMounts(true). This will disable wicket:bookmarkablePage functionality and no one will be able to reach that page. Prio: Critical -> Major.
        Hide
        Martin Grigorov added a comment -

        Wicket 1.4:

        curl -max-redirs 0 -D/dev/stdout 'http://martin-laptop/4196-14/helloworld/?wicket:bookmarkablePage=:org.apache.wicket.markup.html.pages.BrowserInfoPage&cto=Foobar%3f%0d%0aEvilHeader:%20SPLIT%2f%0d%0aAnotherEvilHeader:%20HEADER'
        HTTP/1.1 302 Moved Temporarily
        Date: Tue, 08 Nov 2011 13:19:55 GMT
        Server: Apache/2.2.16 (Ubuntu)
        Location: http://martin-laptop/4196-14/helloworld/Foobar? EvilHeader: SPLIT/- AnotherEvilHeader: HEADER
        Transfer-Encoding: chunked
        Content-Type: text/plain

        <html><body><p>Redirecting to <a href="http://martin-laptop/4196-14/helloworld/Foobar?
        EvilHeader: SPLIT/-
        AnotherEvilHeader: HEADER">http://martin-laptop/4196-14/helloworld/Foobar?
        EvilHeader: SPLIT/-
        AnotherEvilHeader: HEADER</a></p></body></html>

        Voila!

        Show
        Martin Grigorov added a comment - Wicket 1.4: curl - max-redirs 0 -D/dev/stdout 'http://martin-laptop/4196-14/helloworld/?wicket:bookmarkablePage=:org.apache.wicket.markup.html.pages.BrowserInfoPage&cto=Foobar%3f%0d%0aEvilHeader:%20SPLIT%2f %0d%0aAnotherEvilHeader:%20HEADER' HTTP/1.1 302 Moved Temporarily Date: Tue, 08 Nov 2011 13:19:55 GMT Server: Apache/2.2.16 (Ubuntu) Location: http://martin-laptop/4196-14/helloworld/Foobar? EvilHeader: SPLIT/- AnotherEvilHeader: HEADER Transfer-Encoding: chunked Content-Type: text/plain <html><body><p>Redirecting to <a href="http://martin-laptop/4196-14/helloworld/Foobar? EvilHeader: SPLIT/- AnotherEvilHeader: HEADER"> http://martin-laptop/4196-14/helloworld/Foobar? EvilHeader: SPLIT/- AnotherEvilHeader: HEADER</a></p></body></html> Voila!
        Hide
        Martin Grigorov added a comment -

        Here are my results with Wicket 1.5:

        curl -max-redirs 0 -D/dev/stdout 'http://martin-laptop/4196/helloworld/?wicket/bookmarkable/org.apache.wicket.markup.html.pages.BrowserInfoPage&cto=Foobar%3f%0d%0aEvilHeader:%20SPLIT%2f%0d%0aAnotherEvilHeader:%20HEADER'
        HTTP/1.1 200 OK
        Date: Tue, 08 Nov 2011 13:14:59 GMT
        Server: Apache/2.2.16 (Ubuntu)
        Expires: Thu, 01 Jan 1970 00:00:00 GMT
        Pragma: no-cache
        Cache-Control: no-cache, no-store
        Vary: Accept-Encoding
        Transfer-Encoding: chunked
        Content-Type: text/html;charset=UTF-8

        Show
        Martin Grigorov added a comment - Here are my results with Wicket 1.5: curl - max-redirs 0 -D/dev/stdout 'http://martin-laptop/4196/helloworld/?wicket/bookmarkable/org.apache.wicket.markup.html.pages.BrowserInfoPage&cto=Foobar%3f%0d%0aEvilHeader:%20SPLIT%2f %0d%0aAnotherEvilHeader:%20HEADER' HTTP/1.1 200 OK Date: Tue, 08 Nov 2011 13:14:59 GMT Server: Apache/2.2.16 (Ubuntu) Expires: Thu, 01 Jan 1970 00:00:00 GMT Pragma: no-cache Cache-Control: no-cache, no-store Vary: Accept-Encoding Transfer-Encoding: chunked Content-Type: text/html;charset=UTF-8
        Hide
        Martin Grigorov added a comment -

        OK.
        Let's imagine that Tomcat sanitizes the request when using HTTP connector (e.g. port 8080) and doesn't do this thru AJP connector (port 8009). In this case the data after %0d%0a will be parsed as HTTP request headers. So far so good. I can send any headers in the request even without using %0d%0a.
        Now, what bothers me is how these request headers are automatically transferred to the response headers ?

        Show
        Martin Grigorov added a comment - OK. Let's imagine that Tomcat sanitizes the request when using HTTP connector (e.g. port 8080) and doesn't do this thru AJP connector (port 8009). In this case the data after %0d%0a will be parsed as HTTP request headers. So far so good. I can send any headers in the request even without using %0d%0a. Now, what bothers me is how these request headers are automatically transferred to the response headers ?
        Hide
        Igor Vaynberg added a comment -

        wicket is not the one transforming the headers, it is tomcat as youve stated. wicket can simply detect this kind of url attack and abort request processing.

        Show
        Igor Vaynberg added a comment - wicket is not the one transforming the headers, it is tomcat as youve stated. wicket can simply detect this kind of url attack and abort request processing.
        Hide
        Martin Grigorov added a comment -

        I don't see how Wicket will transform the request (GET) parameters to response headers.
        To me it looks like Tomcat is confused while parsing the request data.

        Please specify the exact version of your Tomcat.

        Can you try your HTTPD/JK setup with Wicket 1.5 quickstart app ?
        The url to BrowserInfoPage should be: /wicket/bookmarkable/org.apache.wicket.markup.html.pages.BrowserInfoPage

        Show
        Martin Grigorov added a comment - I don't see how Wicket will transform the request (GET) parameters to response headers. To me it looks like Tomcat is confused while parsing the request data. Please specify the exact version of your Tomcat. Can you try your HTTPD/JK setup with Wicket 1.5 quickstart app ? The url to BrowserInfoPage should be: /wicket/bookmarkable/org.apache.wicket.markup.html.pages.BrowserInfoPage
        Hide
        Gert-Jan Schouten added a comment -

        Well, even if Tomcat sanitizes the requests when called through HTTP and not when it's called through AJP, this still does not make it a Tomcat problem. Wicket should be able to handle unsanitized requests and not be dependent on the container.

        Our apache config is as follows:

        We don't modify the main apache conf file.

        Find below a sanitised copy of our configuration.

        virtual.conf
        ------------

        ServerTokens ProductOnly
        ServerSignature Off

        NameVirtualhost *:80

        <VirtualHost *:80>
        DocumentRoot /var/www/html
        ServerName our.server.name
        ServerAlias server.name

        1. Modified logging format to include X-Forwarded-For IP addresses
          LogFormat "%h %l %u %t \"%r\" %>s %b \"% {Referer}

          i\" \"%

          {User-Agent}

          i\" \"%

          {X-Forwarded-For}

          i\"" combxfwd
          CustomLog "logs/access_log" combxfwd

        ServerSignature Off

        RewriteEngine On

        RewriteRule ^$ /app-context/ [R]
        RewriteRule ^/$ /app-context/ [R]

        JkMount /app-context/* app-lb
        JkMount /app-context app-lb

        1. Only enable these for debugging
          #RewriteLog /tmp/rewrite
        1. Enable compression of text content
          AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/json

        </VirtualHost>

        workers.properties
        ------------------
        ps=/

        worker.list=app01, app02, app-lb
        worker.jkstatus.type=status

        worker.app01.type=ajp13
        worker.app01.host=app01
        worker.app01.port=8009
        worker.app01.socket_keepalive=1

        worker.app02.type=ajp13
        worker.app02.host=app02
        worker.app02.port=8009
        worker.app02.socket_keepalive=1

        worker.ajp13.lbfactor=1

        worker.app-lb.type=lb
        worker.app-lb.balance_workers=app01,app02
        worker.app-lb.sticky_session=1

        mod_jk.conf
        -----------
        LoadModule jk_module modules/mod_jk.so

        JkWorkersFile /etc/httpd/conf.d/workers.properties
        JkLogFile /var/log/httpd/mod_jk.log
        JkShmFile /var/log/httpd/mod_jk.status
        JkLogLevel error
        JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "

        Show
        Gert-Jan Schouten added a comment - Well, even if Tomcat sanitizes the requests when called through HTTP and not when it's called through AJP, this still does not make it a Tomcat problem. Wicket should be able to handle unsanitized requests and not be dependent on the container. Our apache config is as follows: We don't modify the main apache conf file. Find below a sanitised copy of our configuration. virtual.conf ------------ ServerTokens ProductOnly ServerSignature Off NameVirtualhost *:80 <VirtualHost *:80> DocumentRoot /var/www/html ServerName our.server.name ServerAlias server.name Modified logging format to include X-Forwarded-For IP addresses LogFormat "%h %l %u %t \"%r\" %>s %b \"% {Referer} i\" \"% {User-Agent} i\" \"% {X-Forwarded-For} i\"" combxfwd CustomLog "logs/access_log" combxfwd ServerSignature Off RewriteEngine On RewriteRule ^$ /app-context/ [R] RewriteRule ^/$ /app-context/ [R] JkMount /app-context/* app-lb JkMount /app-context app-lb Only enable these for debugging #RewriteLog /tmp/rewrite Enable compression of text content AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/json </VirtualHost> workers.properties ------------------ ps=/ worker.list=app01, app02, app-lb worker.jkstatus.type=status worker.app01.type=ajp13 worker.app01.host=app01 worker.app01.port=8009 worker.app01.socket_keepalive=1 worker.app02.type=ajp13 worker.app02.host=app02 worker.app02.port=8009 worker.app02.socket_keepalive=1 worker.ajp13.lbfactor=1 worker.app-lb.type=lb worker.app-lb.balance_workers=app01,app02 worker.app-lb.sticky_session=1 mod_jk.conf ----------- LoadModule jk_module modules/mod_jk.so JkWorkersFile /etc/httpd/conf.d/workers.properties JkLogFile /var/log/httpd/mod_jk.log JkShmFile /var/log/httpd/mod_jk.status JkLogLevel error JkLogStampFormat " [%a %b %d %H:%M:%S %Y] "
        Hide
        Martin Grigorov added a comment -

        Cite: "When having a Wicket application installed on Tomcat and you call that application through HTTP, Wicket is protected against HTTP Response Splitting"
        This makes me think that this problem is more Tomcat/AJP/HTTPD configuration than problem in Wicket.

        Show
        Martin Grigorov added a comment - Cite: "When having a Wicket application installed on Tomcat and you call that application through HTTP, Wicket is protected against HTTP Response Splitting" This makes me think that this problem is more Tomcat/AJP/HTTPD configuration than problem in Wicket.
        Hide
        Martin Grigorov added a comment -

        Can you provide minimal configuration of HTTPD to be able to make such setup locally to test ?

        Show
        Martin Grigorov added a comment - Can you provide minimal configuration of HTTPD to be able to make such setup locally to test ?

          People

          • Assignee:
            Martin Grigorov
            Reporter:
            Gert-Jan Schouten
          • Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development