Form Token Handling

Available:

Confluence 3.0 and later.

Overview and Purpose

Confluence 3.0 and later employs a new token authentication mechanism that is utilised when Confluence actions are performed either through link request or form submission. This provides Confluence with the means to validate the origin and intent of the request, thus adding an additional level of security against XSRF (Cross-site request forgery). While the core Confluence product and its bundled plugins use this token handling mechanism by default, non-bundled plugins or those developed by third parties may not.

This document is intended for Confluence plugin developers. It provides instructions on how these developers can add this token handling mechanism to their own plugins. Developers should pay particular attention to the DOC:Timeline section, as unmodified plugins may no longer function correctly after the cut-off date.

This change affects:

  • Plugins that provide actions via XWork plugin modules
  • Plugins that create links to, or submit forms to existing Confluence actions

Form Tokens

Confluence 3.0 requires that WebWork actions possess tokens, which are then verified when the form is submitted back to the Confluence server.

This is an "opt in" mechanism, whereby actions must declare that they require a xsrf token to be present in the request. However, in a future version of Confluence, the security policy will switch to a more stringent "opt out" system, where actions must declare that they do not require a token. At this point, any plugin that accepts form submissions and has not been upgraded to use this token authentication mechanism will cease to function.

Instructions for Plugin Developers

Configuring XWork Actions

There are two mechanisms for protecting an XWork action against XSRF through Form Token configuration:

Configuration Location

Steps Required

In the Action class

  1. Locate the method that is called by the action execution (by default this method is called execute())
  2. Add the @com.atlassian.xwork.RequireSecurityToken annotation to this method: @ RequireSecurityToken(true) if the method will require a token, or @ RequireSecurityToken(false) if it will not.
  3. Ensure that your action uses <interceptor-ref name="validatingStack"/> in its <package> definition and has an "input" result - which will be used on token failure.

In atlassian-plugins.xml

  1. Locate the action definition (the <action> element in your <xwork> plugin module)
  2. Add <param name="RequireSecurityToken">true</param> if you wish the action execution to require a token, or change its value to false if it does not.
  3. Ensure that your action uses <interceptor-ref name="validatingStack"/> in its <package> definition and has an "input" result - which will be used on token failure.

We recommend developers use the atlassian-plugins.xml approach, as it will allow their plugins to be backwards-compatible with older versions of Confluence.

Providing the token in HTML Forms

The Velocity macro #form_xsrfToken() will insert the following into your form:

<input type="hidden" name="atl_token" value="[the user's token]">

The Velocity macro #url_xsrfToken() expands to:

atl_token=[the user's token]

So you can do the following

<a href="myaction.action?activate=true&#url_xsrfToken()">Activate</a>

Providing the token in AJAX calls

The Atlassian Javascript Library (AJS) contains a method that will add the security token to an AJAX callback. In order to make this method available, you should place the following call in your Velocity template:

#requireResource("confluence.web.resources:safe-ajax")

This library provides wrappers around JQuery AJAX functions that will include the form token in the AJAX submission. If you are not using the JQuery AJAX functions, you should first update your code to use them directly, then to use the safe version. The following functions are provided:

AJS.safe.ajax()
AJS.safe.get()
AJS.safe.post()
AJS.safe.getScript()
AJS.safe.getJSON()

Accessing the token programatically

To get hold of the current user's token, you will need to make the following call:

new com.atlassian.xwork.SimpleXsrfTokenGenerator().generateToken(httpServletRequest)

For best long-term compatibility, you should retrieve the name of the form parameter to set from the token generator rather than using the literal string "atl_token". For example:

HttpServletRequest req = ServletActionContext.getRequest();
if (req != null)
{
    XsrfTokenGenerator tokenGenerator = new SimpleXsrfTokenGenerator();
    myWebRequest.addParameter(tokenGenerator.getXsrfTokenName(), tokenGenerator.generateToken(req))
    // or: myRequestUrl.append("&" + tokenGenerator.getXsrfTokenName() + "=" + tokenGenerator.generateToken(req));
}
else
{
    // We are not in a web context. Handle this error cleanly.
}

Scripting

Scripts that access Confluence remotely may have trouble acquiring or returning a security token, or maintaining an HTTP session with the server. There is a way for scripts to opt out of token checking by providing the following HTTP header in the request:

X-Atlassian-Token: no-check

Timeline

Confluence 3.0

  • Confluence 3.0 ships with the token generation/checking code in "opt in" mode.

The Future

  • Our plans are to switch Confluence to ship with a more strict "opt out" protection in the future. At this point, plugins that have not been modified to use form tokens may cease to function.
  • We will give more information on these plans once the exact timing is finalised and warn of the changes in advance to give developers time to test plugin compatibility.
RELATED TOPICS

XSRF protection in JIRA.

For more information, refer to the Open Web Application Security Project page.

Was this page helpful?

Have a question about this article?

See questions about this article

Powered by Confluence and Scroll Viewport