If you are developing an application dedicated for organizations and enterprises, you will almost certainly need a Single Sign-On integration, which is now a standard. As SSO is an authentication channel, a gate that keeps your client’s secrets from unauthorized eyes, its architecture and security should definitely be prioritized. However, based on my hands-on experience, Single Sign-On integration functionalities are often implemented poorly, demonstrating a lack of forethought and missed opportunities at best… introducing critical vulnerabilities at worst.
If not asked for directly, SSO does not usually come up during penetration testing scoping. The SSO’s configuration menu is generally hidden somewhere in the depths of an administration panel, treated by applications’ owners rather as an additional feature instead of an alternative to the main login form, as it, in fact, should be. If it is not pre-configured in the test environment, it will probably not be tested at all. Especially since the setup takes some time, not to mention the required knowledge and skills.
This is not how things should be done. I believe that we all share the same goal – to provide a secure SSO feature, both conceptually and technically. However, this means we have to think about it differently – starting with test environments actually integrated with SSO.
Make your SSO integration a security feature your clients truly desire instead of a forgotten liability.
This article will:
- Get you in the right mindset about SSO implementation,
- Explain crucial Single Sign-On concepts,
- Help you introduce security into your SSO architecture.
1. Use an SSO-dedicated and trusted library
The first rule of a secure Single Sign-On integration is using dedicated libraries. Similarly, as with cryptography, you do not want to reinvent the wheel – you not only do not have time for that, but also you will make many security mistakes in the process. The more the library isolates consumers from its inner workings, the less the chance they have to fall victim to a vulnerability.
However, you should take your time to choose a library you can trust – check out the supply chain and how often it is updated. And remember about regular vulnerability scanning using tools like OWASP Dependency-Check!
2. Implement just-in-time provisioning or SCIM
There are four main approaches when it comes to SSO implementation:
- Automatically linked accounts: You can log in via SSO whenever you want – accounts are usually matched based on emails. If you register via SSO, an account in the application is automatically created. Permissions are managed inside the application.
- Manually linked accounts: Once you create an account in the application, you can link it to your SSO account. Permissions are managed inside the application.
- Just-in-time provisioning: create and update users on the fly when they log in for smooth onboarding. If you log in via SSO and do not have an account in the application, it will be automatically created, preferably along with your group settings or permissions.
- SCIM (System for Cross-domain Identity Management): changes made in the central user database (e.g. AD) are automatically propagated to all applications using a standardized SCIM API.
Just-in-time provisioning and SCIM allow for centralized identity management, which eliminates both ample effort and possible human error.
3. Consider Single Sign-On edge cases
When it comes to authentication and authorization processes, you should always expect the unexpected. Let’s take a look at two examples.
As you create or link accounts in the application based on the Identity Provider’s response, you should always make sure that you base it on a unique user identifier. In OpenID Connect, it will be the subject field of an ID token (sub). If you want to link accounts based on an email, make sure to check the value of email_verified claim. Also, if you allow for separate local account creation, make sure you verify the user’s email address, or you might be vulnerable to account pre-hijacking.
Another case worth discussing is when a user belongs to multiple organizations in a multi-tenant application, and every organization sets up their own SSO. How does it affect the SSO flow and architecture? What happens when they authenticate using the first organization’s SSO and then try to switch to the other one? What if only one of the organizations enforces 2FA? These are only examples of questions that should be asked during threat modeling of your solution.
4. Test access control
If your application allows a Single Sign-On configuration, there is usually a setup form hidden deep in the admin panel that makes it possible to set up an SSO authentication. Make sure to add access control to your list of test cases, including:
- Function level access control – unauthorized access to the SSO configuration panel as a low-privileged user – aiming for privilege escalation in your own company.
- Cross-tenant data-level access control – unauthorized access to another company’s SSO configuration panel as a different company admin – aiming for a takeover of a different tenant.
Check out all of the SSO-related configuration methods – not only Identity Provider setup, but also, e.g., disabling the 2FA requirement and, obviously, the SCIM API, if you offer one.
5. Aim for intuitive configuration of your SSO
During the last two years, I have tested many SSO integrations – and I have often had to do integration by myself. Sometimes, it was a pleasure, and after 10 minutes, everything was set up (just think: paste the URL of your Identity Provider, add some details, and everything will be taken care of). Sometimes, though, there is just a big blank input field, and you have to figure it out yourself – not so intuitive.
The same goes for Identity Providers – doing the KeyCloak setup for the first time can be a real headache, even though it is very flexible if you know your RFCs. However, the more options there are, the more chances someone will disable some crucial security option.
However, I am all for including some advanced security options, which are disabled by default but can be configured for extra resilience – like SAML AuthnRequest signature check or a shorter validity time for an OAuth access token… as long as the end user will still be secure without switching them on.
6. Prepare for offboarding
People come and go – and if you do not have an offboarding procedure, you might end up with some ex-employees with access to your critical systems. If you design an SSO integration functionality, you should also keep offboarding in mind.
- If an application does not offer a user any other login option aside from SSO, when a user loses access to the SSO (e.g. is disabled in the AD), they also lose access to the application. However, the user will still exist inside the application – it might be a great idea to, e.g., highlight inactive users in the admin panel and recommend disabling them periodically.
- If you offer a local login option as an alternative to the SSO, ex-employees might still have access to the application if they set up a password before having the SSO disabled. Let your customers know that if they choose not to enforce the SSO, users have to be disabled manually in the application by an administrator.
- If you use SCIM, the user account in the application will be disabled as soon as their main account is terminated (e.g. in AD) due to the automatic propagation of account updates. Nothing to worry about.
Of course, there are always exceptions if you offer anything out of the ordinary, like a possibility to generate API keys. Will they also be disabled automatically when a user who created them is disabled? Try to brainstorm about possible authentication side channel threats!
7. Remember about administrator lock-out prevention
As I already mentioned, offboarding might be a lot easier if an application enforces SSO. However, this leads us to another possible problem – what if SSO stops working? Is there any alternative available for an administrator to access the application in such a case?
One of the possible approaches is to provide administrators with a one-time password that makes it possible to log in using normal credentials (preferably, with a 2FA code). Such a feature might also be restricted to specific IPs.
I believe that every application meant for business should offer a possibility to configure SSO – which is a rare case of a security feature that actually increases user’s convenience. However, if you choose this path, do not do it half-heartedly:
- Include SSO in your threat modeling and treat it with as much care as you would treat the main login form.
- Configure test environments to use SSO.
- Make sure both an SSO login and an SSO configuration panel are within the scope of the penetration tests.
If you have any security doubts about the implementation of SSO in your case and need support, we will be happy to help you in this matter. Use our contact form at the top of this page, or just click here.