DWR

improve the CSRF handling with something to solve problems with servlet filters that force the HttpSession behind DWR's back

Details

  • Type: Improvement Improvement
  • Status: Resolved Resolved
  • Priority: Minor Minor
  • Resolution: Fixed
  • Affects Version/s: None
  • Fix Version/s: 3.0.RC2
  • Component/s: Security
  • Documentation Required:
    Yes
  • Description:
    Hide
    Mike:
    I recently tried enabling the CSRF protection on a DWR application configured with JCIFS, Samba's Java library for NTLM (Microsoft's Single-Sign-On solution for IE/IIS), see http://jcifs.samba.org/src/docs/ntlmhttpauth.html.
     
    I discovered that I got the (now infamous) "Session Error" on the first request, but there was no problem for subsequent requests. I found the cause was that the JCIFS NtlmHttpFilter was creating the HttpSession during its authentication handshaking with the browser, and the browser then joined the session during the handshaking.
    Scenario:
     
    client call -> engine.js -> browser http stack -> NtlmHttpFilter
    - no JSESSIONID yet so engine.js sends batch with empty JSESSIONID for CSRF check
    - no JSESSIONID yet so browser http stack doesn't supply any cookie in request
     
    NtlmHttpFilter -> request.getSession()
    - the JCIFS filter forces creation of session to save some handshaking parameters
     
    browser http stack <- NtlmHttpFilter
    - the JCIFS filter responds with an NTLM handshaking packet to the browser
    - the app-server will now add a "Set-Cookie" header with the JSESSIONID (!)
     
    browser http stack -> NtlmHttpFilter -> DwrServlet
    - the browser responds with a new POST containing NTLM handshaking stuff
    - but now it has joined the session and also sends a JSESSIONID Cookie header (!)
    - when the request reaches DwrServlet there will be a valid session id, but the JSESSIONID copy supplied in the batch from engine.js is still empty as the browser POST body was generated before joining the session, so the CSRF protection will invalidate this request.
     
    Note1: there are actually more steps to the NTLM handshaking than I showed here.
    Note2: you will only see the problem if the session has not been joined before the first DWR call. In my case all non-DWR resources were cached in the browser so they would not generate any requests creating the session, and DWR would get the first request.
     
    The evilness in this scenario is that the servlet filter is both forcing creation of the HttpSession *and* generating extra responses/requests that communicate with the browser http stack, without coming back to the DWR client side.
     
    I had a look in the JCIFS source code and it looks like the filter wouldn't have to force the session. There have previously been requests to correct this behaviour. I made a short post about the "NtlmHttpFilter forcing sessions" issue, not going into detail, but the response was nil.
     
    Anybody here with connections in the Samba camp and know a way to make them interested in solving this?
    Show
    Mike: I recently tried enabling the CSRF protection on a DWR application configured with JCIFS, Samba's Java library for NTLM (Microsoft's Single-Sign-On solution for IE/IIS), see http://jcifs.samba.org/src/docs/ntlmhttpauth.html.   I discovered that I got the (now infamous) "Session Error" on the first request, but there was no problem for subsequent requests. I found the cause was that the JCIFS NtlmHttpFilter was creating the HttpSession during its authentication handshaking with the browser, and the browser then joined the session during the handshaking. Scenario:   client call -> engine.js -> browser http stack -> NtlmHttpFilter - no JSESSIONID yet so engine.js sends batch with empty JSESSIONID for CSRF check - no JSESSIONID yet so browser http stack doesn't supply any cookie in request   NtlmHttpFilter -> request.getSession() - the JCIFS filter forces creation of session to save some handshaking parameters   browser http stack <- NtlmHttpFilter - the JCIFS filter responds with an NTLM handshaking packet to the browser - the app-server will now add a "Set-Cookie" header with the JSESSIONID (!)   browser http stack -> NtlmHttpFilter -> DwrServlet - the browser responds with a new POST containing NTLM handshaking stuff - but now it has joined the session and also sends a JSESSIONID Cookie header (!) - when the request reaches DwrServlet there will be a valid session id, but the JSESSIONID copy supplied in the batch from engine.js is still empty as the browser POST body was generated before joining the session, so the CSRF protection will invalidate this request.   Note1: there are actually more steps to the NTLM handshaking than I showed here. Note2: you will only see the problem if the session has not been joined before the first DWR call. In my case all non-DWR resources were cached in the browser so they would not generate any requests creating the session, and DWR would get the first request.   The evilness in this scenario is that the servlet filter is both forcing creation of the HttpSession *and* generating extra responses/requests that communicate with the browser http stack, without coming back to the DWR client side.   I had a look in the JCIFS source code and it looks like the filter wouldn't have to force the session. There have previously been requests to correct this behaviour. I made a short post about the "NtlmHttpFilter forcing sessions" issue, not going into detail, but the response was nil.   Anybody here with connections in the Samba camp and know a way to make them interested in solving this?

Activity

Hide
David Marginian added a comment - 07/Aug/10 7:16 AM

Won't this be resolved as part of our proposed changes for DWR-26?

Show
David Marginian added a comment - 07/Aug/10 7:16 AM Won't this be resolved as part of our proposed changes for DWR-26?
Hide
Mike Wilson added a comment - 15/Sep/10 11:39 AM

This issue has now been resolved and the CSRF protection doesn't base itself off the HttpSession any longer. See description of changes in DWR-26.

Show
Mike Wilson added a comment - 15/Sep/10 11:39 AM This issue has now been resolved and the CSRF protection doesn't base itself off the HttpSession any longer. See description of changes in DWR-26.

People

Dates

  • Created:
    13/Mar/07 1:25 PM
    Updated:
    15/Sep/10 11:39 AM
    Resolved:
    15/Sep/10 11:39 AM