- [Update May 7 2021] - Please upgrade to Atlassian Connect Spring Boot 2.1.5 or later, 2.1.4 regressed on the fix introduced in 2.1.3
What is changing?
Atlassian is making a breaking API change to Atlassian Connect in Jira and Confluence Cloud to mitigate a vulnerability in the verification of the qsh claim in Connect JWT authentication.
Is my app impacted?
If your app uses an authentication descriptor setting other than none, then it’s highly likely your app is impacted and will need to be updated.
This vulnerability affects apps regardless of how they are installed; apps listed on the Marketplace and apps installed via the UPM “dev mode” are affected .
If your app does not use context JWTs (see below), you must still opt-in to the breaking changes as soon as possible.
Apps running on Bitbucket Connect are not affected .
Why is it changing?
When Atlassian makes a request from Jira or Confluence to a Connect app there’s two forms of authentication that are used depending on how the app is embedded in the products:
- An iframe or server-to-server JWT : For Connect modules (web pages, web panels, etc) and lifecycle hooks
- A context JWT : For securely passing product UI context to an app’s server as described in the cacheable app iframes guide.
Connect apps are expected to validate these tokens to verify the authenticity of the request. The verified JWT will tell the app which user is interacting with the app, which part of the app they’re interacting with, and the context for where the app is embedded inside Jira or Confluence.
Because iframe JWTs are exposed to end users, they contain a qsh (query string claim) that provides a way for Connect apps to validate that the app URL and query string haven’t been tampered with. Context JWTs do not contain a qsh claim, and are free to be used against any app endpoint. This is problematic as:
- The Connect JWT specification does not clearly document how apps should handle iframe JWTs and context JWTs differently (as the difference between them is subtle).
- Some apps, and app frameworks, may accept context JWTs in the place of iframe JWTs which may bypass the URL tampering checks described above.
What do I need to do?
We advise vendors to follow the app incident management guidelines if you determine exploitation of the vulnerability within your environment.
To prevent context JWTs from being accepted by default for any app endpoint, Atlassian is planning to add qsh claims to context JWTs for all apps by Jun 7, 2021. As soon as possible, we ask that you that follow the instructions below to ensure your app is compliant with these changes.
Running an Atlassian-supported Connect framework
- Update Atlassian Connect Spring Boot, or Atlassian Connect Express to the latest version; and
- [Update May 7 2021] - Please upgrade to Atlassian Connect Spring Boot 2.1.5 or later, 2.1.4 regressed on the fix introduced in 2.1.3
- Opt-in to the updated context JWTs by adding a new context-qsh element to the apiMigrations section of the app descriptor.†
- Update your app endpoints that are designed to work with context JWTs to accept a static qsh of context-qsh‡
- We strongly recommend having separate endpoints for each type of JWT. To avoid subverting qsh iframe validation you should not accept both context JWTs and iframe JWTs on a single endpoint.
- The qsh enforcement in these new framework versions is backwards compatible, so the change will work with both tenants that have the updated qsh context JWTs and tenants that are yet to upgrade your app
- Test and deploy your app.
† Your descriptor should look like this:
...
"apiMigrations": {
"context-qsh": true
}
...
‡ for Atlassian Connect Express set skipQshVerification by passing true to addon.authenticate. This will allow the endpoint to be called with a context JWT .
app.get('/example', addon.authenticate(true), (req, res) => {
// ...
res.status(200).send('ok')
});
If your app already uses addon.authenticate() for your iframe or server-to-server endpoints and addon.authenticate(true) (or addon.checkValidToken()) for the endpoints your front-end uses, then you do not need to change your Atlassian Connect Express app code.
For Atlassian Connect Spring Boot annotate methods with @ContextJWT:
@ContextJwt
@RequestMapping(value = "/example", method = RequestMethod.GET)
public ResponseEntity<Void> exampleEndpoint(@AuthenticationPrincipal AtlassianHostUser hostUser) {
// ...
return ResponseEntity.ok().build();
}
Running a custom implementation
If you’re using a framework other than Atlassian Connect Spring Boot, or Atlassian Connect Express, then please follow these steps to ensure your app correctly verifies the qsh claim:
- Opt-in to the updated context JWTs by adding a new context-qsh element to the apiMigrations section of the app descriptor.†
- Follow Understanding JWT for Connect apps to validate JWTs using your app secret
- Reject any JWT that does not have a qsh claim
- For app endpoints that need to accept a context JWT, such as requests from your app front-end to back-end:
- Validate the qsh claim is set to context-qsh instead of building a query string hash from the request path and parameters
- Do not apply this to all endpoints by default, only for endpoints that need to accept context JWTs
† Your descriptor should look like this:
...
"apiMigrations": {
"context-qsh": true
}
...
For reference, a pseudo-code example of an endpoint that accepts context JWTs:
Function HandleAPIRequest(request)
JWT <- request.Header['Authorization'] or request.QueryString['jwt']
claims <- ValidateJWTSignature(JWT)
if not claims then
// JWT signature validation failed
return Error(Unauthorized)
if not claims.qsh then
// Missing QSH claim - reject
return Error(Unauthorized)
// Normal QSH verification based on the request parameters
requestQsh <- ComputeQSH(request)
if requestQsh != claims.qsh and claims.qsh != 'context-qsh' then
// QSH verification failed
return Error(Unauthorized)
// success, let the request through
return OK
By when do I need to do it?
Under the recently announced Vulnerability Management Program for Marketplace Apps, Atlassian will create AMS issues for eligible apps with a target SLA to patch this vulnerability.
To reduce the security impact of this vulnerability, the change will be automatically applied to all apps that haven’t used context JWTs for the last two weeks. There should be no impact as a result of this change. If your app has been incorrectly identified as being unaffected, please create an issue in our developer support portal for this change to be reversed for your app.
Enforcement of this breaking change is planned for all apps byJun 7, 2021. If you do not patch your app to mitigate this vulnerability and opt-in to the context-qsh API migration before this date, your app may stop working.
Need help?
Please reply to this announcement if you have any questions about this change, or if you need to discuss the situation in more detail.