Hello everyone,
I have reimplemented secret token protection as a component, see:
https://svn.xwiki.org/svnroot/xwiki/contrib/sandbox/xwiki-csrftoken
It uses a page from the "core-functionality" application I proposed lately:
https://svn.xwiki.org/svnroot/xwiki/contrib/sandbox/xwiki-application-core-…
This component has 3 methods:
Return the current token
String getToken()
Check if the given token is valid
boolean isTokenValid(String token)
Return the URL of a resubmission page (see explanation later)
String getResubmissionURL()
These methods are accessible from scripts using ScriptService, e.g. from
velocity:
$!{services.csrf.getToken()}
$services.csrf.isTokenValid("$!{request.getParameter('form_token')}")
$!{services.csrf.getResubmissionURL()}
The tokens are stored in an internal map, one token per user. A current
limitation is that the tokens never expire (unless the component is
reinitialized).
This is not nice, but can easily be changed later, once login/logout
events and a scheduling component are available.
The resubmission page is shown in case the token verification fails. It
shows a message to the user, explaining what happened and asks for
confirmation. If the user clicks "Yes", the blocked request continues
with a correct token, if the user clicks "No", the page returns back to
the originating page.
The idea behind resubmission is to prevent users from loosing data in
case of bugs, server restarts or similar issues, but still stop CSRF
attacks. A limitation is that Ajax requests without correct token will
still just fail until the user reloads the page.
CSRF checks can be disabled by setting
core.csrftoken.enabled = false
in xwiki.properties, this is the default for now.
The component as is does nothing even when enabled, the actual checks
will need to be done in all cases where some data is changed, i.e. in
actions, some templates, REST component etc. All forms, links and Ajax
requests used to modify data will need to include a parameter called
"form_token" with the value of the current token. If the data is changed
in velocity (some templates do this), then a CSRF check must be added there.
I have added an updated patch for most important applications, all
templates and actions to the JIRA issue:
http://jira.xwiki.org/jira/browse/XWIKI-4873
Not yet protected is the REST API and some applications: officeimporter,
ircbot, photoalbum, invitation, annotations, search.
The protection seems to work, but I really need more people to try it
out on a larger wiki.
A big TODO are the selenium tests (especially selenium 1). They often
use a direct URL to delete/create/edit a page, such requests fail when
CSRF checks are enabled.
I would really like to see CSRF protection included into XWiki (disabled
by default) even though many tests fail with enabled CSRF checks (25
ui-tests, 18 selenium-tests). This is already a very big patch, and
fixing all tests first will make it even bigger and harder to apply.
WDYT?
Alex
On 03/07/2010 08:46 PM, Alex Busenius wrote:
Hi,
I would like to add support for secret token verification to prevent
CSRF attacks (see
http://jira.xwiki.org/jira/browse/XWIKI-4873).
The main idea is to add a random token as a parameter to each request
that requires edit/comment/admin rights and check that this token is
present on the server side. Since there are many ways one can modify
documents, it would require many changes all over the place, in particular:
* add a public method to XWikiContext:
String getSecretToken()
that generates a random token and caches it in the session
* add a public method to XWikiRightService*:
boolean isRequestLegitimate(String action, XWikiContext context)
to check if the given action is allowed to be executed
* add the following API methods to Context:
String getSecretToken()
boolean checkSecretToken()
for including the secret token into forms/AJAX requests and checking
that the current request is legitimate
* add a new configuration parameter core.useSecretTokenValidation for
disabling this functionality, and the corresponding method
useSecretTokenValidation() to CoreConfiguration and
DefaultCoreConfiguration
* use the secret token (hidden input for forms or parameter of GET
requests) in all templates (*.vm files in web/standard and skins,
velocity macros in applications/**/resources/*.xml)
* check the secret token in Save/Delete/Upload/etc.-Actions and throw
an exception to deny the access if the check fails
* check the secret token in all templates that directly modify data
(e.g. web/standard/src/main/webapp/templates/admin.vm)
* fix all selenium tests that directly modify pages using the
open(...) method
* make sure nothing else is broken
WDYT?
Thanks,
Alex
_______________________________________________
devs mailing list
devs(a)xwiki.org
http://lists.xwiki.org/mailman/listinfo/devs