CSRF Tokens with CSRF guard
CSRF Tokens
Jahia protects all action triggering URLs having the .do
suffix against CSRF attacks with the usage of secure random tokens. This is handled by the Jahia CSRF Guard module, which is installed on default.
How it works
With the help of webfilters we modify the HTML of pages including action links or form submissions, to obtain a dynamic javascript. You will see the following line in the HTML of such a page:
<script type="text/javascript" src="/modules/CsrfServlet"></script>
This javascript detects forms and links and will add the CSRF token. It's added by a filter and should be in all pages served by Jahia.
- In forms, a hidden field is added :
<form method="POST" action="/sites/digitall/home/csrftest/area-main/dummy-csrf-action-caller.modifyTextAction.do">
<input type="hidden" name="jcrNodeType" value="jnt:testContent">
<input type="hidden" name="jcrRedirectTo" value="/sites/digitall/home/csrftest">
<input type="hidden" name="jcrResourceID" value="aacd982b-0bc4-46e6-8f25-3c6fa732a31f">
<input type="hidden" name="newText" value="Hello Planet!">
<button type="submit">Say Hello Planet</button>
<input type="hidden" name="CSRFTOKEN" value="D3C4-2YHX-RR1R-2C64-3T74-T04V-5VL0-0T0G">
</form>
- In tags containing src or href attribute, the token is added in the URL :
- For XHR calls, the token is transparently added into an HTTP header when the call is executed :
Disabling CSRF-guard for an action
There may be cases, where a CSRF token is not needed for an action, for instance when the action does not trigger any state changes.
For that a configuration file can be packaged directly in your module. This is the best way to allow CsrfGuard executing your actions as these settings will be used on module deployment. Here is a quick way to do it:
- First create a new configuration folder
src/main/resources/META-INF/configurations
- Create a new file
org.jahia.modules.jahiacsrfguard-yourModule.cfg
in this folder. Note this filename needs to be unique as it will be deployed in yourdigital-factory-data/karaf/etc
. So we suggest replacing yourModule with the name of your module. So for instance if your module name is test-module then you should create such a filesrc/main/resources/META-INF/configurations/org.jahia.modules.jahiacsrfguard-test-module.cfg
- Edit this new configuration file, and whitelist all your action URLs, which will not require a CSRF token, with such a line:
whitelist = *.action1.do,*.action2.do
Allow GET methods
By default, all the actions are restricted just to POST requests. You can explicitly declare that GET is allowed in your spring file with requiredMethods="GET,POST"
Override CSRF guard configurations
Since versions 1.5.0 and 2.4.0 of the jahia-csrf-guard module, it is possible to override the csrfguard properties (org.owasp.csrfguard.*
) by modifying /karaf/etc/org.owasp.csrfguard.cfg
.
For instance with org.owasp.csrfguard.Enabled = false
you can (temporarily) disable the CSRF filter without having to stop the jahia-csrf-guard module.
Error when referer check does not match the protocol
In the case where your site is accessed via SSL protocol (https) only up to a front-end proxy and then towards the Jahia just with http, you may see CSRF related errors looking like this in the log.
ERROR [CsrfGuard] - Referer domain https://<your-page> does not match request domain: http://<your-page>
This should be solved by following the recommendation in the knowledge base article: Jahia links are not in https
Alternatively you could also set the following property in /karaf/etc/org.owasp.csrfguard.cfg
:
org.owasp.csrfguard.JavascriptServlet.refererMatchProtocol = false
Using tokens per-page
From jahia-csrf-guard version 3.0.0 onwards it is possible to enable the creation of random unique tokens per-page (and session) as opposed to just a unique per-session prevention token, which then is the same on all pages. This is a defense in depth strategy to limit the impact, whenever a token gets leaked to an attacker. With a leaked token per-session a CSRF attack could be carried out against any form or action in the entire webapp, as long as the victim's session is active. With a token per-page the CSRF attack could only be carried out against a small subset of resources.
Starting with Jahia 8.2.0, the token per-page implementation is activated by default. Note that it requires testing and possible code changes within custom templates or modules. You should especially check that the back button of the browser or a form re-submit in the same session still works as expected. Furthermore there may be an issue if you call AJAX requests to actions during the page initialization phase (see this linked discussion to get hints about possible solutions). Also starting to use tokens per-page may reveal a mistake, when HTML fragments using tokens are getting cached in Jahia. You have to set a view related cache.expiration
property to 0
(see View Caching).
The usage of tokens per-page can get deactivated in Jahia 8.1+ with setting the following property in /karaf/etc/org.owasp.csrfguard.cfg
:
org.owasp.csrfguard.TokenPerPage = false