Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

  1. You are viewing a Jira issue
  2. You leave your computer for over 5 hours --or--  in another tab you log out and back in to Jira.
  3. You return to the issue, and without refreshing the page  try to attach a file or image to the issue.

    It also happens if you click the 'Create' button to create a new issue, and on the 'Attachment' field try to upload an attachment.

Background: CSRF attacks

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/kittens containing:

Code Block
<img<a srchref="https://jira.yourcompany.com/secure/admin/user/AddUser.jspa?email=evil%hax0rsevil%40hax0rs.com&fullname=Mr+HaX0rHax0r&username=hacker&password=fake123hacker123&selectedApplications=jira-software&Create=Create+user" width="0" height="0" border="0">>Click me!</a>

If you visit a site containing that HTML, your browser will blindly request that HTTP URL to the 'image', and (if you are a logged-in Jira admin) create a new hacker Jira account!can trick a Jira administrator into visiting that site and clicking that link, a new hacker  account is created in Jira.

 Why 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, as it does for all HTTP requests which is scoped to jira.yourcompany.com.

Note
titleSameSite=Lax

Until 2020, you could even embed the malicious URL in a <img>  tag, and not even need the user to click That is no longer possible since SameSite=Lax became the default, 'Lax' meaning the JSESSIONID  cookie is sent when a link is clicked, but not for non-interactive URLs like in <img>.

Jira's CSRF defenses

The atl_token CSRF token

Jira'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:

Then when receiving a request to AddUser.jspa  (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  param 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)

Note

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:

  • *.jspa Webwork actions like CreateIssueDetails.jspa, whose execute()  method has a @requiresXsrfCheck  annotation. For the implementation, see JiraActionFactory.java which invokes DefaultXsrfInvocationChecker.java.
  • POST, DELETE AND put operations on REST resources, like , submitted via HTTP forms. See Atlassian REST API design guidelines for the rules here. This is implemented in XsrfResourceFilter, which also eventually leads to DefaultXsrfInvocationChecker.java  

Origin/Referer checking

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

Jira
serverAtlassian JIRA
serverId144880e9-a353-312f-9412-ed028e8166fa
keyJRASERVER-63915

CSRF tokens in Jira

). Origin  and Referer  tell Jira where the request originated – https://hax0rs.com in our example.  This is implemented in XsrfResourceFilter.java .


Jira's CSRF Implementation Details

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:

Image Added

But where does Jira store its copy of the parameter? In two places actually:

  1. the user session
  2. in the user's browser as a cookie.

The atlassian.xsrf.token  session attribute

While you are actively using Jira, Jira maintains a 'session' for you. A session is just a handful of key:value pairs. Incidentally, if 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:

The session attribute we care about here is 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). When Jira generates the HTML for pages like AddUser.jspa  it includes this

The atlassian.xsrf.token cookie

If you examine the cookies your browser associates with Jira, you'll see an atlassian.xsrf.token  value as a hidden atl_token  parameter:

Image Removed

Your Jira 'session' doesn't last forever. The default session timeout is 5 hours (or 18000 minutes, the 'Max Inactive Interval' in the JSP output).  When your session times out, or when you explicitly log out and back in again, your session is lost and so is your XSRF token . Next time you log in you'll get a new randomly generated atlassian.xsrf.token.

An SRF token is a secret bit of text known only to the Jira server and your browser. In your browser you can see the same XSRF token in a cookie by clicking on the padlock icon to the left of the URL:
Image Removed

cookie:

Image Added

This is sent along with every HTTP request.

It would therefore be easy to think thatthis 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

...

What's happening is as follows. When you are actively using Jira, the Jira server keeps a 'session' for you,
Your browser must include the XSRF token with every request, usually as a cookie. If a request comes without a matching XSRF token, Jira will assume that the request did not come from a trusted source, and will respond with an error.

This XSRF token stays the same for the duration of your session, which is 5 hours by default (5h = 18000 minutes in the Max Inactive Interval  session attribute). After 5 hours of inactivity, or if you log out and back in again, you get a new session and a new XSRF token.

...

titleXSRF in cookies!?

.

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:

Image Added

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!



The failing edge-cases

Submitted xsrf 40206:

Image Added

Next request, submitted 08713

Image Added

Image Added


Image Added

I have to say, I do not understand how Jira's CSRF protection works. CSRF is an attack where, e.g. The whole point of a CSRF token is that it isn't  just another cookie that the browser blindly attaches to a request. The presence of a CSRF token in a request is meant to signify that 

When atlassian.xsrf.token  cookie isn't used

Image Removed