2

I've been playing with the new csrf functionality in Spring Security 3.2.0.RC1, and noticed that it doesn't seem to work with enctype="multipart/form-data" forms.

I have a simple Spring form:

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
...
<form:form action="${pageContext.request.contextPath}/model/create" modelAttribute="myForm" enctype="multipart/form-data">

and the hidden csrf input is being rendered as expected:

<input type="hidden" value="..." name="_csrf">

but the request fails the csrf check (it works fine if I remove enctype="multipart/form-data"). The only way i've found around this is to append "?_csrf=..." to my action url, which is ugly as the token then appears in the address bar on redirect. Has anyone experienced the same/found a nice solution?

JimJay
  • 349
  • 2
  • 8
  • 17
  • Possible duplicate of [Spring CSRF token does not work, when the request to be sent is a multipart request](http://stackoverflow.com/questions/21514074/spring-csrf-token-does-not-work-when-the-request-to-be-sent-is-a-multipart-requ) – Andrei Epure Mar 30 '17 at 17:21

1 Answers1

5

Currently the CSFR protection requires/reads a request parameter, however due to your different type of form the form content isn't available as request parameters. If you add it to the URL it will be available as request parameter.

Inside the DispatcherServlet there is multipart detection and such a request is wrapped in an implementation of a MultipartHttpServletRequest, which decodes the multipart request and makes the content available as request parameters.

However the Spring Security filters execute before that. Until there is a final solution you can configure the MultipartFilter and execute it before the Spring Security filter chain. That basically pulls the wrapping en decoding in front of the DispatcherServlet. One thing to remind here is that you need to also put it before the Spring Security filter.

Example configuration and additional solutions can be found in the Spring Security reference guide.

M. Deinum
  • 115,695
  • 22
  • 220
  • 224
  • NOTE: The Jira that @m-deinum referenced is no resolved. You can find how to do CSRF protection with multipart/form-data here http://docs.spring.io/spring-security/site/docs/3.2.x-SNAPSHOT/reference/html/csrf.html#csrf-multipart – Rob Winch Sep 27 '13 at 21:47
  • I have added the MultipartFilter to our web.xml as mentioned in the latest Spring Security documentation, but still getting an Access Denied error whenever a controller method expecting a multipart file is invoked. The relevant configuration can be seen at https://gist.github.com/manish-in-java/8661970. – manish Jan 28 '14 at 03:50
  • You have added it but your configuration is wrong. YOu placed the `MultipartResolver` in the wrong configuration. The `MultipartFilter` only reads from the root application context (the one loaded by the `ContextLoaderListener`, move it to the xml file loaded by it). – M. Deinum Jan 28 '14 at 07:34
  • @M.Deinum I'm getting empty file and no part data in Filter after applying the MultipartFilter. Can you suggest something ? – Lalit Mehra Oct 23 '15 at 13:49
  • @M.Deinum found it ... changed the location of bean MultipartFilter to applicationContext.xml and it worked – Lalit Mehra Oct 23 '15 at 14:21