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-functionality 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 > [email protected] > http://lists.xwiki.org/mailman/listinfo/devs > _______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs

