Expand my Community achievements bar.

SOLVED

AEM 6.1 CSRF token rejection

Avatar

Level 1

A form that POSTs data that used to work in AEM6.0 no longer works in AEM6.1 due to CSRF token rejection
When the form is submitted we recieve the following error in the log:

POST /apps/tools/components/xsrftest/run.html HTTP/1.1] com.adobe.granite.csrf.impl.CSRFFilter isValidRequest: empty CSRF token - rejecting
POST /apps/tools/components/xsrftest/run.html HTTP/1.1] com.adobe.granite.csrf.impl.CSRFFilter doFilter: the provided CSRF token is invalid

How can the form provide a CSRF token be that satisfies com.adobe.granite.csrf.impl.CSRFFilter?

1 Accepted Solution

Avatar

Correct answer by
Level 10

Here is the answer to this:

With 6.1, we added CSRF (Cross-Site Request Forgery) protection and you need to ensure that the CSRF token is included.

This should be handled automatically if you are using AEM's version of jQuery. This library has the code to get the token and add it to all XHR and forms.

If you absolutely need to use a different version of jQuery (why?) and/or don't use jQuery at all, then you can include the 'granite.csrf.standalone' client library and it will do the same hooks.

Here is the updated AEM 6.1 doc for this use case: 

https://helpx.adobe.com/experience-manager/using/custom-sling-servlets6_1.html

View solution in original post

10 Replies

Avatar

Employee Advisor

Some slides [1] from today's ConnectCon might also be interesting for you.

[1] http://www.slideshare.net/antoniosanso/cqcon2015

Avatar

Level 10

Security
6.1 includes a range a new and improved capabilities to maintain a secure deployment and run a secure web property. Most notable is a new Cross-Site Request Forgery (CSRF) protection, with that the server does extra checks on POST, PUT and DELETE HTTP requests from browser to avoid CSRF attacks.

Note: With previous releases, for deployments that leverage the Token/Cookie authentication, sticky session was required between multiple publish instances. AEM 6.1 no longer requires sticky session on the load balancer to keep a token/cookie based authentication. This is possible due to a new Crypto Token implementation.

Further, the 'nosamplecontent' server run mode was extended to also deploy a range of 'secure by default' best practices, that with previous releases had to be manually configured.

Consult the AEM 6.1 Forms documentation: 

https://helpx.adobe.com/aem-forms/6-1/help-tutorials.html

Avatar

Level 1

A clarification, I'm not using an out of the box product like 'AEM forms'.

I have a simple jsp with an html form tag and a submit button that is trying to post data to another jsp, all hosted on the same author instance.

Please forgive me if the information for submitting a CSRF token on a form is included in the documentation link you sent, there are dozens of links on that page, none of which look relevant.

Avatar

Level 10

I thought you may be using AEM forms -- that is why i send the link.

I am going to try and post data to AEM 6.1(from a JSP that contains a forms element) and see if i get the same results.  

Avatar

Level 1

Here is a sample form I'm working with:

<%@include file="/libs/foundation/global.jsp"%> <html> <form method="POST"> <table> <tr> <td>Enter Value:</td> <td><input type="text" name="myvalue" value="test" /></td> </tr> <tr> <td> </td> <td><input type="submit" /></td> </tr> </table> </form> </html>

Avatar

Level 10

I confirmed this behavior: 

[img]WrongPOst.png[/img]

A 403 was returned - i will track down what needs to occur. 

Avatar

Correct answer by
Level 10

Here is the answer to this:

With 6.1, we added CSRF (Cross-Site Request Forgery) protection and you need to ensure that the CSRF token is included.

This should be handled automatically if you are using AEM's version of jQuery. This library has the code to get the token and add it to all XHR and forms.

If you absolutely need to use a different version of jQuery (why?) and/or don't use jQuery at all, then you can include the 'granite.csrf.standalone' client library and it will do the same hooks.

Here is the updated AEM 6.1 doc for this use case: 

https://helpx.adobe.com/experience-manager/using/custom-sling-servlets6_1.html

Avatar

Level 3

Just a side note...  The RECAP tool (https://marketing.adobe.com/resources/content/resources/en/exchange/marketplace/apps/RECAP.html) in Package Share does not work with AEM 6.1 due to the CSRF protection change.  This is what happens when trying to create an address:

POST /home/users/x/x6TeJhtxt3GQ4GfZmzI9/recapAddresses/* HTTP/1.1] com.adobe.granite.csrf.impl.CSRFFilter doFilter: the provided CSRF token is invalid
POST /home/users/x/x6TeJhtxt3GQ4GfZmzI9/recapAddresses/* HTTP/1.1] com.adobe.granite.csrf.impl.CSRFFilter isValidRequest: empty CSRF token - rejecting

Avatar

Level 2

Just want to add that you can also retrieve the current users CSRF token at /libs/granite/csrf/token.json. If you're doing an XHR request you can add this token in as a value for the header 'CSRF-Token' in the POST request.

But as Scott said, the cq.jquery clientlib does all of that for you.

Avatar

Level 4

Hi,

I'm testing a nosamplecontent install on AEM 6.1sp2 with Java 8.  When I do a clean start of the server with a clean  browser cache and login as admin to CRXDE to execute Create > New Project and enter data, I get an error like this CSRF error in this thread.  I tried removing the POST filtering as a workaround.  I wonder if the community can provide some insight to nosamplecontent testing creation of new projects?

Here's the error that occurs the first time:

POST /libs/crxde/createProject HTTP/1.1] org.apache.sling.startupfilter.impl.StartupFilterImpl Filter service disabled

POST /libs/crxde/createProject HTTP/1.1] com.adobe.granite.csrf.impl.CSRFFilter isValidRequest: empty CSRF token - rejecting

POST /libs/crxde/createProject HTTP/1.1] com.adobe.granite.csrf.impl.CSRFFilter doFilter: the provided CSRF token is invalid

POST /libs/crxde/createProject HTTP/1.1] com.day.cq.wcm.core.impl.components.ComponentCacheImpl Loaded 882 components in 358ms

Here's the reoccurring error every time afterward (tried to remove non-adobe packages to make the thread smaller; substituting ...)

POST /libs/crxde/createProject HTTP/1.1] org.apache.sling.servlets.post.impl.operations.ModifyOperation Unable to create resource named createProject in /libs/crxde

POST /libs/crxde/createProject HTTP/1.1] org.apache.sling.servlets.post.impl.operations.ModifyOperation Exception during response processing.

javax.jcr.nodetype.ConstraintViolationException: No default node type available for /libs/crxde/createProject

        at org.apache.jackrabbit.oak.util.TreeUtil.addChild(TreeUtil.java:186)

...

        at com.day.cq.wcm.core.impl.WCMDebugFilter.doFilter(WCMDebugFilter.java:133)

        at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68)

        at com.day.cq.wcm.core.impl.WCMComponentFilter.filterRootInclude(WCMComponentFilter.java:371)

        at com.day.cq.wcm.core.impl.WCMComponentFilter.doFilter(WCMComponentFilter.java:171)

        at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68)

        at com.day.cq.personalization.impl.TargetComponentFilter.doFilter(TargetComponentFilter.java:96)

...

        at com.day.cq.dam.core.impl.servlet.ActivityRecordHandler.doFilter(ActivityRecordHandler.java:155)

...

        at com.adobe.granite.requests.logging.impl.RequestLoggerImpl.doFilter(RequestLoggerImpl.java:124)

        at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68)

        at com.adobe.granite.csrf.impl.CSRFFilter.doFilter(CSRFFilter.java:201)

...

        at com.day.cq.wcm.core.impl.AuthoringUIModeServiceImpl.doFilter(AuthoringUIModeServiceImpl.java:364)

        at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68)

        at com.day.cq.wcm.core.impl.warp.TimeWarpFilter.doFilter(TimeWarpFilter.java:106)

        at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68)

        at com.day.cq.wcm.mobile.core.impl.redirect.RedirectFilter.doFilter(RedirectFilter.java:240)

        at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68)

        at com.adobe.cq.social.commons.cors.CORSAuthenticationFilter.doFilter(CORSAuthenticationFilter.java:91)

        at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68)

        at com.day.cq.analytics.provisioning.impl.UserAuthenticationRequestFilter.doFilter(UserAuthenticationRequestFilter.java:119)

        at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68)

        at org.apache.sling.engine.impl.debug.RequestProgressTrackerLogFilter.doFilter(RequestProgressTrackerLogFilter.java:95)

        at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68)

        at com.day.cq.wcm.foundation.forms.impl.FormsHandlingServlet.doFilter(FormsHandlingServlet.java:269)

        at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68)

        at com.day.cq.theme.impl.ThemeResolverFilter.doFilter(ThemeResolverFilter.java:76)

        at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68)

        at com.adobe.granite.optout.impl.OptOutFilter.doFilter(OptOutFilter.java:74)

        at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68)

        at com.day.cq.wcm.core.impl.WCMRequestFilter.doFilter(WCMRequestFilter.java:90)

        at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68)

        at com.adobe.cq.history.impl.HistoryRequestFilter.doFilter(HistoryRequestFilter.java:107)

        at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68)

        at com.day.cq.wcm.designimporter.CanvasPageDeleteRequestFilter.doFilter(CanvasPageDeleteRequestFilter.java:88)

        at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68)

        at org.apache.sling.rewriter.impl.RewriterFilter.doFilter(RewriterFilter.java:83)

        at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68)

        at com.adobe.granite.httpcache.impl.InnerCacheFilter.doFilter(InnerCacheFilter.java:77)

        at com.adobe.granite.httpcache.impl.InnerCacheFilter.doFilter(InnerCacheFilter.java:56)

        at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68)

        at org.apache.sling.i18n.impl.I18NFilter.doFilter(I18NFilter.java:129)

        at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68)

        at com.adobe.granite.rest.impl.servlet.ApiResourceFilter.doFilter(ApiResourceFilter.java:68)

        at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68)

        at com.adobe.cq.dam.s7imaging.impl.auth.MemoryTokenAuthHandler.doFilter(MemoryTokenAuthHandler.java:156)

        at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68)

        at org.apache.sling.bgservlets.impl.BackgroundServletStarterFilter.doFilter(BackgroundServletStarterFilter.java:135)

        at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68)

        at com.adobe.cq.social.ugcbase.security.impl.SaferSlingPostServlet.doFilter(SaferSlingPostServlet.java:132)

        at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68)

        at com.adobe.granite.resourceresolverhelper.impl.ResourceResolverHelperImpl.doFilter(ResourceResolverHelperImpl.java:84)

...

        at com.adobe.granite.license.impl.LicenseCheckFilter.doFilter(LicenseCheckFilter.java:308)

..

        at org.apache.felix.http.base.internal.DispatcherServlet.service(DispatcherServlet.java:67)

        at javax.servlet.http.HttpServlet.service(HttpServlet.java:725)

        at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:808)

        at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:587)

        at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:221)

        at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1127)

        at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515)

        at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)

        at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1061)

        at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)

        at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:215)

        at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)

        at org.eclipse.jetty.server.Server.handle(Server.java:497)

        at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:310)

        at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:257)

        at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:540)

        at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635)

        at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555)

        at java.lang.Thread.run(Thread.java:745)