Have you ever tried to attach a file or image to a Jira issue, and got the error Jira could not attach the file as there was a missing token. Please try attaching the file again. ? This commonly happens when:

The 'missing token' in question is a CSRF token used to prevent CSRF (cross site request forgery) attacks.
An example of a CSRF attack would be as follows. An attacker creates a HTML page at https://hax0rs.com containing:
<a href="https://jira.yourcompany.com/secure/admin/user/AddUser.jspa?email=evil%40hax0rs.com&fullname=Mr+Hax0r&username=hacker&password=hacker123&selectedApplications=jira-software&Create=Create+user">Click me!</a> |
If you can trick a Jira administrator into visiting that site and clicking that link, a new hacker account is created in Jira.
Why did Jira, upon receiving that AddUser.jspa HTTP request, trust the sender? Because your browser identified the request as "coming from you" by including a identifying JSESSIONID cookie, which is scoped to jira.yourcompany.com.
Until 2020, you could even embed the malicious URL in a |
atl_token CSRF tokenJira's main defense against CSRF is to generate a random bit of text (the 'CSRF token') just for you when you log in, and embed it in every HTML form that, if submitted, would changes server state (like adding users). The field is called atl_token:
![]()
When the user submits a form in Jira (on the 'Add User' admin page, for example), this atl_token parameter is submitted in the POST body. Jira checks that the atl_token value is correct before performing the operation. The CSRF token value is a secret known only to Jira and your browser, and changes after every login or session expiry (5h of inactivity). An attacker won't know the correct atl_token parameter to include in their forged URL.
This is known in the literature as the synchronizer token pattern (OWASP)
Only some Jira operations get token-based CSRF protection. It seems a bit haphazard, e.g. creating a Jira issue is CSRF protected, but adding a comment isn't. Specifically, CSRF protection is applied to:
|
In addition to the atl_token mechanism, Jira also implements the 'Defence In Depth Techniques' on the OWASP page. Specifically, the Origin and Referer request headers are checked for REST resources (but perhaps not yet for .jspa requests - see ).
Origin and Referer tell Jira where the request originated – https://hax0rs.com in our example. This is implemented in XsrfResourceFilter.java .
Back to those atl_token parameters.
We know that the token is initially generated by Jira when you log in, and is embedded in the returned HTML:
![]()
But where does Jira store its copy of the parameter? In two places actually:
atlassian.xsrf.token session attributeWhile you are actively using Jira, Jira maintains a 'session' for you. A session is just a handful of key:value pairs. If you are a Jira administator you can see your session's attributes by dropping sessionattributes.jsp into your atlassian-jira/secure/ directory, and hitting the /secure/sessionattribute.jsp URL:

There in the session, you see where Jira is storing your CSRF token: in the atlassian.xsrf.token attribute (Jira uses 'XSRF' as a synonym for CSRF).
atlassian.xsrf.token cookieIf you examine the cookies your browser associates with Jira, you'll see an atlassian.xsrf.token cookie:

This is sent along with every HTTP request.
It would therefore be easy to think that this atlassian.xsrf.token cookie is the thing in the request that needs validating. Isn't the server just comparing the atlassian.xsrf.token request cookie with the atlassian.xsrf.token session attribute is knows is correct, and if they match, passing the CSRF check?
No! Remember that the atlassian.xsrf.token cookie is sent by the browser, and will always be present in malicious and non-malicious requests. Its value will always be correct, because cookies aren't under the attacker's control. It is the atl_token form parameter which needs validating, not the atlassian.xsrf.token request cookie.
In fact, when the server receives a request, it could compare the atl_token form parameter with either the atlassian.xsrf.token request cookie, or the atlassian.xsrf.token session attribute. In fact Jira does both (in XsrfTokenStrategy.java ).
The reason Jira sets the atlassian.xsrf.token cookie is because sessions expire after 5 hours, but cookies don't expire. Typically your browser will store 3 Jira cookies:

When you request a Jira page first thing in the morning, your server session has expired, so JSESSIONID is invalid and a new session will be created. The seraph.rememberme.cookie cookie will automatically log you in to Jira. Your empty session won't have a atlassian.xsrf.token attribute in it, but because there is a trusted atlassian.xsrf.token cookie, Jira uses the cookie value for the session attribute (in XsrfTokenAdditionRequestFilter.java ). That means that if your first JIRA request of the day was an operation requiring CSRF validation, then the validation should pass, as the atl_token in the page is validated against the cookie / session attribute. Neat!
Submitted xsrf 40206:

Next request, submitted 08713


