Scenario
- Single-page (AngluarJS) web application using HTTP API for client-server communication
- Spring Security configured to use CSRF protection (via XML)
- CSRF token is usually sent in request header (works fine)
- Application needs to support file upload in IE9
Problem
The file upload is acheived though a multipart/form-data POST request. Usually this is done using client-side AJAX, but IE9 does not support FileAPI (http://www.w3.org/TR/FileAPI/).
The work-around for IE9 is to create a form in a hidden iframe, and submit the form. The CSRF token is added to the request body by adding it as a form input -- reason being that I cannot manipulate request headers to add the CSRF header before form submission.
Spring Security's org.springframework.security.web.csrf.CsrfFilter first tries to get the CSRF token from the headers, and if not found then tries to get it from the parameters (via HttpServletRequest.getParameter())
This doesn't work for a multipart request with the CSRF token in the body -- getParameter() will always return null.
(As an aside, this call to getParameter() also reads the request InputStream to the end, so we're forced to wrap the request before it gets to the CsrfFilter so that the request InputStream is 'cached')
I want to create a CsrfFilter that invokes getPart(), but cannot do so while still using the nice+clean Spring Security XML namespace elements.
The reason is that there is no place to include a custom CSRF filter in the configuration -- and the CsrfConfigurer is hard-coded to use the org.springframework.security.web.csrf.CsrfFilter, so one cannot be injected.
I can add code to the overridden getParameter() method of my request wrapper class to also attempt to parse the parameter out of multipart request -- but really this is quite tricky to get right, and would rather avoid such maintenance costs.
TL;DR
- We can't add CSRF token to request headers, need to add to request body
- Request is multipart/form-data
- Spring Security CSRF filter is not configurable to parse CSRF token from multipart request
Any help -- either suggestions to fix on the client-side or server-side -- is welcome!
TIA