Important Update Effective February 1, 2024!
Due to recent changes in Jira and Confluence, we've made the tough decision to discontinue the OpenID Connect (OIDC)/OAuth app and no longer provide new versions for the newest Jira/Confluence releases as of January 31, 2024.
This is due to some necessary components no longer shipping with Jira/Confluence, which would require some extensive rewrites of the OIDC App.
Important Update! This app will be discontinued soon!
Due to recent changes in Jira, which no longer ships with some components required for our Read Receipts app to run, we've made the tough decision to discontinue the app, as of Februar 5, 2025.
Important Update! This app will be discontinued soon!
We've made the tough business decision to discontinue the app, as of January 11, 2025.
Hardening security with HTTP security headers
By default, our app adheres to the same HTTP headers (and respective protections) that the Atlassian Server and Data Center applications use. By itself there is no need to do anything, if you are happy with what Atlassian does out of the box.
However we see some customers going beyond that & deploying their Atlassian Server and Data Center applications behind application firewalls, reverse proxies etc. Some of these customers go as far as adding additional headers and measures that go beyond the default.
This article discusses these measures and the compatibility of our app with those.
Generally, there are several types of attacks on web applications and their users. While they always require an error or an oversight to exist in the web application, there are a couple of ways such problems can be mitigated should they occur. One of them is the use of several HTTP security headers in conjunction with a modern web browser that understands these.
To mitigate any unknown attacks of certain types such as Cross-Site Scripting (XSS), Clickjacking or Cross-Frame Scripting (XFS), we recommend adding a couple of HTTP headers to responses sent from the Atlassian applications.
This document tries to give you some pointers on how to implement these hardening measures on your own system, but it does not claim to be a comprehensive guide. Always test these settings is a non-production environment since your situation may vary and these settings might not work in your case if, for example, some other apps require some changes to these policies.
Existing security headers
Atlassian applications in current versions already send a couple of security headers, but these are on the conservative side and might be improved upon for our app. These headers are:
Header name | Header value |
---|---|
Content-Security-Policy | frame-ancestors 'self'; |
X-Content-Type-Options | nosniff |
X-Frame-Options | sameorigin |
X-XSS-Protection | 1; mode=block |
While the X-Content-Type-Options, X-Frame-Options and X-XSS-Protection headers are usually sufficient, there are additional headers that can be set and the Content-Security-Policy can be tightened.
Note that on Confluence, these headers are not sent automatically for apps. We have opened a bug report with Atlassian to investigate that: https://jira.atlassian.com/browse/CONFSERVER-57471. Please note that public access has been revoked for this security-related bug ticket.
On Bitbucket, only the X-XSS-Protection header is sent. To fix these issues, just have your reverse proxy or load balancer send these headers.
Improving upon the existing headers
For our app's pages (reachable via "/plugins/servlet/samlsso"), the content security policy can be restricted even further and new headers can be introduced.
Recommended additional header configuration
Header name | Header value |
---|---|
Content-Security-Policy | default-src 'self' 'unsafe-inline' 'unsafe-eval'; frame-ancestors 'self'; img-src 'self' data: https://www.gravatar.com; |
Feature-Policy | camera 'none'; fullscreen 'none'; geolocation 'none'; microphone 'none'; payment 'none'; speaker 'none'; usb 'none'; vibrate 'none'; vr 'none'; |
Referrer-Policy | strict-origin |
Strict-Transport-Security | strict-transport-security: max-age=31536000 |
Content-Security-Policy
The content security policy defines which sources may be used for which parts of the pages. In our case, we require 'self', 'unsafe-inline' and 'unsafe-eval' due to Atlassian's Javascript and CSS. For the image-src, we explicitly allow gravatar.com, since some applications allow using it for user avatars.
Note that for testing the Content-Security-Policy on your system, you can give a report-uri and use the Content-Security-Policy-Report-Only header instead of Content-Security-Policy as detailed on MDN. We also found this blog article by a Dropbox engineer on testing CSPs and handling reports helpful. You may also want to use a service like report-uri.com to help debug your CSP.
Also note that the frame-ancestors might have to be modified. For more details, see On using the host application in an iframe.
Feature-Policy
As another mitigation technique, you can explicitly disallow some features in case an attacker is able to inject code. The prepared statement should disallow most functions that can be used to spy on users (microphone, camera, geolocation) or trick them into doing something (payment, usb, fullscreen, vr). If you, for some reason, do require one of your SAML SSO page templates to use one of these functionalities, such as maybe geolocation-based IdP selection, you'll have to modify this header.
Referrer-Policy
This is a privacy feature. The referrer (or 'referer') header is sent to a server when you visit a website and were previously on another website. The target site can use that header to see where you came from. The value we chose strict-origin will cause the referrer header to not be sent when a user visits a site on a different server. Disabling it should not cause any harm, but it can also not be completely ruled out that some IdPs don't require it. It may also mess with analytics a bit, but that should be uncritical in this use case.
Strict-Transport-Security
Use this with caution! If this header is delivered to a browser via an HTTPS connection, this browser will now always visit this website only via HTTPS and never via HTTP any more. Use this header only if absolutely know that your application will never have to be accessed via HTTP via that address. Note that you can still access it via HTTP via another address if needed.
On using the host Atlassian Data Center or Server application in an iframe
If the application is embedded in another website via frame or iframe, then the Content-Security-Policy and X-Frame-Options must be modified. Typical scenarios include:
- Running the application in an intranet portal
- Using Jira Service Desk issue collectors
- Using Confluence as a knowledge base in Jira Service Desk
If any of these cases apply and you're having trouble embedding the application, then you might have to modify the aforementioned frame-related headers. Check your browser console errors regarding embedding to determine the cause for the issues.
For example, if you want to embed the application on https://intranet.example.com, then you need to modify the following headers:
Header name | Header value |
---|---|
Content-Security-Policy | frame-ancestors 'self' https://intranet.example.com; |
X-Frame-Options | allow-from https://intranet.example.com |
For more informations on this, check Atlassian's documentation.
How to set HTTP security headers
These headers are usually set by either the host application or a reverse proxy / load balancer. Here are some instructions on how to set the headers in a couple of popular reverse proxies / load balancers. If yours isn't in the list, consult your software's or service's documentation on how to achieve this.
NGINX
For each header you want to overwrite, add the following statements, adapted to the headers you want to set, to the appropriate server block:
location /plugins/servlet/samlsso {
add_header "Content-Security-Policy" "default-src 'self' 'unsafe-inline' 'unsafe-eval'; frame-ancestors 'self'; img-src 'self' data: https://www.gravatar.com;";
add_header "Feature-Policy" "camera 'none'; fullscreen 'none'; geolocation 'none'; microphone 'none'; payment 'none'; speaker 'none'; usb 'none'; vibrate 'none'; vr 'none';";
add_header "Referrer-Policy" "strict-origin";
}
For more information, check out the NGINX documentation for add_header.
Note that this configuration may leave you with multiple versions of the headers, for example the CSP header. You can have nginx replace the existing headers by using the ngx_headers_more module and its more_set_headers directive.
Apache httpd
Make sure mod_headers is enabled. Then add the following statements, adapted to the headers you want to set, to the appropriate Proxy block in the appropriate Virtual Host config:
<Proxy "http://your-backend/plugins/servlet/samlsso">
Header set "Content-Security-Policy" "default-src 'self' 'unsafe-inline' 'unsafe-eval'; frame-ancestors 'self'; img-src 'self' data: https://www.gravatar.com;"
Header set "Feature-Policy" "camera 'none'; fullscreen 'none'; geolocation 'none'; microphone 'none'; payment 'none'; speaker 'none'; usb 'none'; vibrate 'none'; vr 'none';"
Header set "Referrer-Policy" "strict-origin"
</Proxy>
For more information, check out the Apache httpd documentation for Header set.
Microsoft IIS
You can use the HTTP Response Headers GUI in IIS Manager or add the following to your web.config:
<system.webServer>
<httpProtocol> <customHeaders> <add name="Content-Security-Policy" value="..." /> </customHeaders>
</httpProtocol>
</system.webServer>
For more information, check out the Microsoft IIS documentation for customHeaders.
Further steps & information
Here are a couple of links from which we drew information while compiling this document:
- Mozilla Developer Network documentation on the headers:
- Reverse Proxy header configuration:
- Tools:
- Scan and evaluate your installation's security headers: https://securityheaders.com/
- Collect your CSP reports: https://report-uri.com/ (Includes a free tier)
- Other helpful resources:
- Scott Helme's blog: https://scotthelme.co.uk/hardening-your-http-response-headers/ also contains resources about how to set these headers
- Dropbox blog post on testing CSP: https://blogs.dropbox.com/tech/2015/09/on-csp-reporting-and-filtering/
- Blog post on caveats in add_header in NGINX: https://www.peterbe.com/plog/be-very-careful-with-your-add_header-in-nginx