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:
While you are actively using Jira, Jira maintains a 'session' for you. A session is just a handful of key:value pairs in memory, grouped by 'session id', which is associated with your browser requests with the JSESSIONID cookie your browser sends.
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
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).
There are a few more wrinkles, but that is the essence of Jira's CSRF protection: all state-modifying HTTP requests must have an
atl_token field, whose value must match the atlassian.xsrf.token session parameter.
It would therefore be easy to think thatthis atlassian.xsrf.token cookie 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?
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
Why does Jira even set 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 token cookie? No idea. The general question of "why send the CSRF token as a cookie" is asked and answered on Stackoverflow. I'm not sure if any of those advantages actually apply to Jira. Certainly Jira does not populate the
When sessions expire..
One nice thing Jira could have done with the incoming atlassian.xsrf.token attribute in it, but because there is a trusted cookie it is re-initialize the atlassian.xsrf.token session parameter from the cookie if the session has expired. Then if your session expired overnight, 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!
The failing edge-cases
Submitted xsrf 40206:
Next request, submitted 08713
and you had a Jira form half-filled in, the submit (next morning) would work, as the session atlassian.xsrf.token would be seeded from the atlassian.xsrf.token cookie. Currently that doesn't happen: if the session has expired,
XsrfTokenAdditionRequestFilter.java (very early in the filter chain) just generates a new atlassian.xsrf.token session attribute, which is then compared to the
atl_token field, fails to match, and you get a 'missing token' error to brighten your Monday morning:
..to Be Continued
Apologies to anyone reading, but there is no conclusion yet. The fix suggested above (copy the token from cookie to session) could be implemented as a custom servlet filter, even implemented as a plugin. If I ever do so I will update this post.