Announcing the Connect app authorization guide

Connect for Jira and Confluence apps can be invoked in a few ways; directly as a module from Atlassian products, via a web trigger, or the app frontend invoking backend app endpoints. As documented in the Security for Connect apps guide, each request must be authenticated to determine it was genuinely sent by the Atlassian product, and then the request must be authorized to determine if the user has permissions to perform the action.

Through analysis of many Marketplace apps we found apps would leverage the permission model defined by Atlassian products to determine what actions within the app could be taken by the user. For example, only Jira or Confluence admins would have the ability to manage settings the app offers. To determine whether or not a request should be permitted, the app needs to somehow determine if the current user has administrator permissions. We also found it wasn’t always clear when apps should be performing explicit authorization checks versus relying on solely on Connect module conditions or ACT_AS_USER impersonation.

After analysing the security findings from app reviews and the Marketplace Security Bug Bounty Program, we observed that authorization issues in apps would often lead to users getting permissions they shouldn’t have, or accessing content or issues they don’t have permissions to see.

To make authorization for Connect apps easier, we have:

  1. Reduced the scopes Connect apps require to query for Confluence content or Jira permissions, so only the READ scope is required rather than ADMIN. This helps ensure apps aren’t requesting more scopes than necessary.

  2. Introduced a basic authorization middleware into Atlassian Connect Express 7.1.5 to make authorization of app frontend to backend interactions via context JWTs easier.

  3. Developed a guide to help Connect developers understand when authorization checks are required, and the two ways authorization can be enforced.

Please familiarise yourself with the Connect app authorization guide and apply the advice to your apps. If you have any questions or feedback, please reply to this thread or reach out to us on the Developer Support Service Desk.

Cheers,
Zac

Security Engineer, Ecosystem Security

14 Likes

Awesome!

May I suggest analyzing another crucial part of the equation, which you will not see in the bugrowd program: the sheer complexity of Jira and Confluence permission management?

Some of the elevated permission issues reported to us were caused by not knowing the right permissions to check for. And I’ve been administering jira since 2009!

5 Likes

This is good stuff. I’d suggest also improving the workflow around adding new permissions to the app descriptor. As it is today, when a new permission is added, it requires admin approval (as should be). However, admins can hold off on upgrading indefinitely. Supporting old versions of the app descriptor can be difficult or impossible, but not supporting them means breaking the app for a significant portion of users who cannot be identified for effective communication.

The incentive here is for new apps to request more permissions than strictly necessary in the case that they may be needed later.

9 Likes

@zsims thanks for the write-up, very helpful.

1 Like

Thanks for the feedback remie. Do you mean it’s not clear how Connect Conditions map to permissions and how to check them? Or another aspect of permissions?

1 Like

Thanks for the feedback. The re-consent from admins is important, especially as app scopes increase. Do you have ideas for how this approach can be improved from your point of view? We’ve discussed the concept of users “nudging” admins to perform the upgrade. It’s also come up with changes that require descriptor updates (like Action required: Atlassian Connect vulnerability allows bypass of app qsh verification via context JWTs).

1 Like

We never have any issues with applying Connect Conditions. But that is just one part of the story, because we also need to add permission checks in our REST API.

We basically serve a static React application and do not use server-side rendering. As such, Connect Conditions will not help, as we expose a REST API that interacts with Jira/Confluence/3rd parties and exposes sensitive information.

As such, we also need to add permission checks to that REST API. That is the part which is very elusive and would really benefit from a reconsideration in terms of the host application permissions model.

The first step is that the actual list of permissions is not documented. This is because it is considered dynamic and can only be fetched via REST API permissions endpoint. It is difficult to digest that list and see which of those permissions actually relate to a set of privileges and whether we should allow that.

For instance, if I want to allow access to a certain REST API for Project Administrators, and limit that to PROJECT_ADMIN I might get support requests from users that have the global Administrator permission but do not have the project specific PROJECT_ADMIN permission. They will have the ability to actually administer the project based on their global permission, so now I also need to add the global ADMINISTER permission to my permissions check.

This is a simple illustration, but the fact is: users can have so many different ways of achieving permissions to perform a specific operation, and the list of available permissions and their impact is so badly documented, that it is sometimes hard to harden a REST endpoint properly.

5 Likes

This is just a rough idea: add an vendor defined (optional) time limit to upgrades. Atlassian will send automatic email warnings similar to if billing fails. If no action is taken, app will automatically disable at deadline.

I also had an idea for handling this from vendor side. If we add a query param to the install hook containing app version, then we can track which instances are on which app version and communicate to admins appropriately or even render warnings on app pages.

1 Like

@remie thanks for the detailed reply.

The first step is that the actual list of permissions is not documented. This is because it is considered dynamic and can only be fetched via REST API permissions endpoint

Custom permissions are dynamic, there is a static set of project and global permissions supported in Jira documented under project + global permission keys. Would it help if these were mapped to descriptions, e.g. “ADD_COMMENTS = the user has permission to add comments to a given issue/project.”?

REST API for Project Administrators, and limit that to PROJECT_ADMIN […] now I also need to add the global ADMINISTER permission […] They will have the ability to actually administer the project based on their global permission

We really need both, as there are certainly some apps that change behaviour based on whether the user is a project admin (global admin aside). Would you expect that PROJECT_ADMIN resolves to true if the user is a product administrator? Or an additional permission? The goal being to make it easier to harden a REST endpoint as you highlighted.

These are just examples. My point was that Jira & Confluence user permission management is a hot mess. The fact that there is a “Permissions Helper” feature in Jira should indicate that Atlassian has also acknowledged that this is a pain point for customers. I would not be surprised if a significant part of Solution Partner business goes to help setting up permissions :joy:

I’m not saying I have any specific answers here on how to solve this, because it is far too complex. The only thing I want to emphasise is that analysing BugCrowd tickets only tells half the story. The reason there are so many elevated permissions issues is not solely because of bad implementation on the Atlassian Marketplace side, it is also caused by the (historic) mess that is Jira / Confluence permissions management.

2 Likes

@jasonboileau these are great ideas, thanks for sharing. Given we often need these for security (Action required: Atlassian Connect vulnerability allows bypass of app qsh verification via context JWTs) I’ve raised this internally - I’ll share the progress as this travels along.

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.