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?
Won't this be resolved as part of our proposed changes for
DWR-26?DWR-26?