We had a scenario while building a form on Java DXA 1.7 and tried to have it submit via POST, not GET. We had the form working perfectly via GET, but when we changed the method to POST the response was a 403 Forbidden. We poked in many directions, such as directory security settings and web.xml configs. In the end it was the CSRF configuration built into DXA that was the answer…
Before I get too far into this post, I have to give credit to Abhishek Galoda in his Stack Exchange Q&A on this: https://tridion.stackexchange.com/questions/17295/http-status-403-for-spring-mvc-page-on-post-operation.
CSRF stands for Cross-Site Request Forgery (CSRF) that can allow an attacker to trick the victim into requesting a state change on the server, such as executing a financial transaction (I am not claiming to be an expert on CSRF by any means, but that’s the gist). The Spring framework has a security module to aid in the prevention of this type of attack. By default it blocks POST requests due to an exploit. For reference, here is the link to the Spring docs on it: https://docs.spring.io/spring-security/site/docs/current/reference/html/csrf.html. In essence, you have to pass a CSRF token together with the POST request to ensure the submitter is legit. Looks like a bit of work to get it all wired up though. Luckily, SDL DXA conveniently implements this module for us, so we don’t have to do much work to use it. Unfortunately the DXA documentation is a bit of a maze and the best we could find is a reference on how to disable CSRF to make POST work (here:Â http://docs.sdl.com/LiveContent/content/en-US/SDL%20DXA-v7/GUID-F51DCF89-451A-4D69-BA9C-801D3D17A6D0). However, disabling the prevention mechanism is not the correct way to enable POST requests. Passing the CSRF token with the request is, as I mention above. So we dug a bit deeper into DXA to get a bit more of an understanding of what and where the implementation of this mechanism lies…
The JAR dxa-common-impl.jar contains the implementation classes, including the JSP tag:
In the form, we now simply use the tag inside your form together with the RequestMapping method POST set in the controller:
Thanks for sharing, Nick!
It seems this has changed in DXA 2.0.0-CTP2. We are able to able to make a POST request without disabling CSRF and without including any csrf-token tag. I don’t see the equivalent page in the DXA 2 documentation, but I’m guessing this logic has been abstracted into the DXA framework so that the developer does not have to consider it…
Thanks Mate, for mentioning my name on your blog !!
Thanks for sharing, Nick! I was able to find the same topic in the DXA 1.7 docs by searching for “CSRF.”
What would it have been less of a maze, though? Would it help to have the docs explain how to correctly handle such posts or was it the structure?
For what it’s worth, I had to recently apologize to Bart for not letting him know a DXA issue he could have easily fixed. He follows the community, but it’d be worth asking for a doc update or leaving a comment.
Great question, Alvin! In the docs the mention of CSRF is on a page called “DXA Java Configuration” which has a lot of info, but only a very very small 2-line blurb about it in the middle of the page. This blurb only states that CSRF protection exists in the implementation and how to disable it (“for whatever reason”), but there is not doc that I’ve found that states on how to submit a POST or work with the configuration beyond disabling it.
Nickoli, thanks for the great input! I am actually the technical writer now supporting DXA, since joining SDL last March. Alvin and Bart passed your feedback on to me, and I’ll be using it to clarify this section and get it updated. Again, thanks!
Wow, I didn’t realize that my small comment would have such an impact. Thanks for jumping on it Julie!