BlogDocumentation
Products
Identity ProtectionIdentity ManagementBlogDocumentation
Vincenzo Iozzo
Vincenzo Iozzo
8 Jan, 2024
Introduction OAuth 2.0 and OIDC authorization at a high level Security best practices Only use authoritative claims Enforce exact paths in OAuth 2.0 providers configuration Avoid the implicit OAuth 2.0 grant type Use Proof Key for Code Exchange (PKCE) to avoid CSRF and interception attacks Verify the token received from a third-party IdP Be mindful of which providers you accept on your website If you are a SlashID customer Conclusion
Security
Single Sign-On implementation: Security Issues and Best Practices

Social logins and OpenID Connect (OIDC) are an extremely effective way to register new users with low friction.

There are many libraries out there that implement OIDC with several providers, however the implementation is very error-prone and can expose an application to account takeover attacks.

In this article, we’ll discuss the common security issues found in OAuth 2.0/OIDC login flows and best practices on how to avoid them.

Single Sign-On implementation: Security Issues and Best Practices

Introduction

Social logins and enterprise connections are popular because they are an extremely effective way to register users lowering sign up frictions (often up to 20% higher conversion or more) as well as a way to connect internal enterprise directories to a SaaS application.

Besides SAML, which is largely used for enterprise directories, the standard for social login is a protocol called OpenID Connect (OIDC). This is an identity layer built on top of the OAuth 2.0 framework. It allows third-party applications to verify the identity of the end-user and to obtain basic user profile information. OIDC uses JSON web tokens (JWTs), which are obtained through flows defined in the OAuth 2.0 specifications.

Unfortunately OAuth 2.0 is a complex protocol and several implementations suffer from security issues.

Just recently Salt Security published a series of blog posts on OAuth 2.0 implementation bugs found in sites such as Booking.com, Kayak, Grammarly, and many more.

This is in addition to the vulnerability reported to Descope that can lead to privilege escalation when using Entra/Azure AD for SSO and the one reported by Truffle Security that could lead to a similar outcome with Google.

In this blog post we summarize the best practices in implementing OAuth 2.0 securely followed by a deeper dive on the risk posed by each.

OAuth 2.0 and OIDC authorization at a high level

Feel free to skip this section if you are already familiar with OAuth 2.0 and OIDC

It would take too long to describe all the possible OAuth 2.0 flows and they are generally well documented online. To summarize in a picture:

OAuth 2.0 flow

At a high-level, here is some contextual information useful for the rest of the article:

  1. Roles:

    • Resource Owner: The user who authorizes an application to access their account.
    • Resource Server: The server hosting the user data.
    • Client: The application wanting to access the user’s account.
    • Authorization Server: The server that authenticates the resource owner and issues access tokens to the client.
  2. Flow:

    • The client requests authorization from the resource owner to access their resources.
    • If the resource owner grants authorization, the client receives an authorization grant, which is a credential representing the resource owner’s authorization.
    • The client requests an access token from the authorization server by presenting the authorization grant and authentication.
    • If the request is valid, the authorization server issues an access token to the client.
    • The client uses the access token to access the protected resources hosted by the resource server.
  3. Authorization Grant Types: OAuth 2.0 defines several grant types but in this article we’ll touch on the two most commonly used ones:

    • Authorization Code: Used with web applications.
    • Implicit: Simplified flow, mostly used by mobile or web applications.
  4. Access Token:

    • This token represents the authorization of a specific application to access specific parts of a user’s data.
    • The client must send this token to the resource server in every request.
    • Tokens are limited in scope and duration.

As it is often explained publicly, OAuth 2.0 doesn’t provide an authentication flow hence it is generally used in conjuction to OpenID Connect (OIDC). OIDC allows clients to verify the identity of an end-user based on the authentication performed by an authorization server, as well as to obtain basic profile information about the end-user. At a high-level:

  1. Roles:

    • End-User: The individual whose identity is being verified.
    • Client: The application requiring the end-user’s identity, typically a web app, mobile app, or server-side application.
    • Authorization Server (OpenID Provider): The server that authenticates the end-user and provides identity tokens to the client.
  2. Flow:

    • The client requests authorization from the end-user. This is typically done through a user agent (like a web browser) and involves redirecting the user to the authorization server.
    • The authorization server authenticates the end-user. This may involve the user logging in with a username and password or other authentication methods.
    • Once authenticated, the end-user is asked to grant permission for the client to access their identity information.
    • After the end-user grants permission, the authorization server redirects back to the client with an ID Token and, often, an Access Token.
    • The ID Token is a JSON Web Token (JWT) that contains claims about the identity of the user. The client will validate this token to ensure it’s authentic.
    • The Access Token can be used by the client to access the user’s profile information via a user-info endpoint on the authorization server.
  3. Scopes and Claims:

    • During the authorization request, the client specifies the scope of the access it is requesting. Common scopes in OpenID Connect include openid (required), profile, email, etc.
    • Claims are pieces of information about the user, such as the user’s name, email, and so forth. These are included in the ID Token based on the requested scopes.

In practice, at a high level, a client is given a client_id and a client_secret. The client initiates a request sending those two parameters among others to the authorization server, the authorization server first verifies the validity of the client_id and client_secret and then proceeds to verify the user. Once that’s done, the user is redirected to a redirect_uri passed to the authorization server by the client. From there on, depending on the OAuth 2.0 flow, there might be further exchanges between the client and the authorization server server.

Security best practices

This is the a list of security checks to perform when implementing OIDC:

  1. Only use authoritative claims
  2. Enforce exact paths in OAuth 2.0 providers configuration
  3. Avoid the implicit OAuth 2.0 grant type
  4. Use PKCE to avoid CSRF and interception attacks
  5. Verify the token received from a third-party IdP and check that the client id is the intended client id for the application
  6. Be mindful of which providers you accept on your website

Only use authoritative claims

This issue has presented itself in a number of different flavors across major identity providers including Microsoft Entra, Google and AWS Cognito. For example, Flickr was compromised through a version of this issue.

Microsoft calls the issue “the false identifier anti-pattern”:

The false identifier anti-pattern occurs when an application or service assumes that an attribute other than the subject of an assertion from a federated identity provider is a unique, durable, and trustworthy account identifier during single sign-on.

Microsoft Entra

The issue stems from the fact that in AzureAD/Entra a user without a provisioned mailbox can have any email address set for their Mail (Primary SMTP) attribute. This attribute is not guaranteed to come from a verified email address.

However most clients retrieving the email address claim through OIDC would treat it as a verified/authoritative email address.

For example, an attacker could have an Azure AD account with an email such as [email protected] and the receiving client would treat that as the valid email address for that user. If Satya Nadella actually had an account in that specific client that could lead to a privilege escalation/unauthorized impersonation where the attacker could impersonate Nadella.

It’s important to note that while this specific issue was about the email address claim in AzureAD, the more general pattern is for clients to always verify which claims are authoritative for a Resource Server and maintain the same “privileges” over them.

Google

In fact, similarly to the Entra issues, researchers at Truffle Security discovered a very similar issue with Google. In particular, it is possible to create a Google account with an existing email. Contrary to the AzureAD case, the ownership of the email is verified. However depending on the implementation of the client this could still lead to two issues:

  1. Insider Threat: an existing employee can create a shadow account (by leveraging the + sign aliases) in the target client/application. If the application allows for multiple idenfiers to be specified or very long-lived tokens, the insider might be able to maintain access to the shadow account even after the employee has left the company/has been terminated. Such a vulnerability was found by Truffle Security in both Zoom and Slack.
  2. Privilege escalation/Unauthorized impersonation: Several researchers have shown how somebody can abuse customer support ticketing systems to impersonate other domains using magic links. In such a scenario, an attacker could gain access to a company application by combining the two issues together.

Note: Google has a OAuth 2.0 claim called email_verified, it might be possible to create Google accounts without any email verification at all leading to more unauthorized impersonation issues.

AWS Cognito

The last example is another variation on this but easier to follow. A website can use AWS Cognito as an OAuth 2.0 provider leading to a similar issue.

As well described in this blog post on Flickr, by default Cognito allows users to change their user attributes, including the email attribute email.

In the case of Flickr, the website was using the standard OIDC flow to authenticate a user and they referenced the email claim without verying the flag in the email_verified claim. This lead to a scenario where an attacker could takeover any Flickr account with a simple process:

  1. Create an attacker account on Flickr and authenticate
  2. Extract the AWS Cognito access token and using the aws cli change the email claim to the victim email
  3. Re-login with the attacker account in (1)

Flickr use the email claim to link the Flickr account to the AWS Cognito user resulting in an arbitrary account takeover.

Enforce exact paths in OAuth 2.0 providers configuration

When a client registers with an Authorization Server generally a redirect_uri has to be specified, the Authorization Server will then verify that the URL passed during the OIDC flow matches the redirect_uri stored for that client.

Unfortunately most Authorization Servers allow wildcards in the path or some even allow no redirect_uri at all. There’s nothing the client can do in the latter case but in the former it is crucial to specify exact urls instead of wildcards.

This is because an attacker can potentially trick a victim into being redirected to a different origin than intended and thus potentially stealing the access token.

Avoid the implicit OAuth 2.0 grant type

The implicit OAuth 2.0 grant type was previously recommended for native apps and SPA applications. In this flow, the access token is returned directly as part of the redirect.

Combining this with the previous issue, can lead to a simple way to impersonate the user by stealing the access token when the user is redirected to a redirect_uri that is attacker-controlled.

Use Proof Key for Code Exchange (PKCE) to avoid CSRF and interception attacks

Cross-Site Request Forgery (CSRF) is a vulnerability that occurs when an attacker can cause a victim to perform an unintended action on a web resource. In the context of OAuth 2.0, a code interception attack is an attack where the attacker intercepts an authorization code and tries to redeem it for a valid access token.

A technique called Proof Key for Code Exchange (PKCE, pronounced “pixy”) was introduced to reduce the risk of CSRF and code interception. PKCE is an addition to any OAuth 2.0 flows.

In summary, the idea is for the application/client to select a secret, one-time nonce that cannot be intercepted by an attacker as it is never sent to the user browser.

When a flow starts, the client hashes the nonce and sends it in the code_challenge parameter to the authorization server. When the user completes the authorization flow and is redirected to the redirect_uri, the client sends the code_verifier in addition to the auth code and the state parameters to the authorization server. The authorization server returns a valid access token only if the hash of the code_verified matches the code_challenge.

The key idea is that an attacker who intercepts the authorization code from the server is unable to redeem it for an access token, as they are not in possession of the code_verifier secret.

The authorization server would reject a token request if the attacker tries to inject an authorization code via CSRF.

PKCE also protects against a network attacker because the attacker would need to inject a code that is bound to the same code challenge that was used initially by the client. While the attacker can create codes bound to arbitrary code challenges, the attacker cannot know the code challenge used in any one legitimate session.

Verify the token received from a third-party IdP

If you do need to support the implicit OAuth 2.0 grant type it is key to verify the token received in the callback as the callback could be invoked by an attacker with a valid access token belonging to a different website.

In this scenario, an attacker can intercept the OAuth 2.0 flow and swap the token with a token issued from an attacker-controlled website. Specifically:

  1. Trick a user into logging-in through OIDC on an attacker-controlled website
  2. Begin the OIDC flow on the target website pretending to be the user. This way the attacker is able to capture the state parameter used by the client and the Authorization Server to identify a “session”
  3. Use the state parameter from (2) combined with the access token for the user obtained in (1) to complete the authentication flow on the target client/website.

To address this problem, it is crucial to confirm that the token received was issued for the client client_id and not for a third party application.

Be mindful of which providers you accept on your website

Duplicated accounts are one of the most vexing issues for both users and companies. On the user side, duplicate accounts lead to frustration and bad experience. On the company side it leads to customer support tickets as well as issues with data analysis.

To address this problem a lot of websites automatically merge accounts if the primary user identifier is the same. In other words, a user who registered with [email protected] and has account number 123 will be treated as the same person if the primary identifier [email protected] comes from OIDC, a magic link or any other authentication method.

This is a more general case of the issues we’ve see in (1), specifically an attacker could impersonate a legitimate user if account merging is turned on a website and the website has one of two issues:

  1. Has a weakness such as trusting a claim that is not authoritative
  2. Supports a OIDC provider for which an attacker can obtain a token and the website is not implementing countermeasures as indicated in the section above

If you are a SlashID customer

Ultimately mitigating these issues requires the expert review of a security engineer or an application security review. However, using a vendor can make the task less daunting. In particular, if you are a SlashID customer we help you in the following ways:

  1. We do not support OAuth 2.0 implicit flow
  2. We enforce PKCE
  3. For all Identity Providers we support, we return an email claim only if it’s verified
  4. We only support SSO providers that we have vetted and consider trustworthy
  5. You can use our SDK to send an email verification link after the user logs in with SSO

Conclusion

Authentication is a typical example of a task that is simple in theory but very hard in practice due to both security and reliability issues. In this blog post we’ve shown a few examples of what could go wrong when implementing OIDC/Social Logins.

If you are interested in implementing social logins and identity securely, get a free account here or reach out to us!

Related articles

Protecting against malicious OAuth 2.0 applications

Security

/ 8 Jan, 2025

Protecting against malicious OAuth 2.0 applications

Several Chrome extension developers were compromised in recent weeks by an attack seeking to create a backdoor in the

extensions.

The root cause of the breach was a phishing email that leveraged OAuth 2.0/OIDC to steal

the user credentials.

This blog post explores the details of such attacks and how SlashID can help detect them and contain

the blast radius.

Vincenzo Iozzo
Vincenzo Iozzo
Navigating PCI DSS 4.0: The Challenge of Non-Human Identities

Security

/ 16 Dec, 2024

Navigating PCI DSS 4.0: The Challenge of Non-Human Identities

The Payment Card Industry Data Security Standard (PCI DSS) has long served as the foundation for organizations handling payment card data, ensuring robust security measures are - in place to protect sensitive information

The release of PCI DSS version 4.0 on March 31, 2022, marked a significant evolution in the standard, introducing requirements and emphasizing areas that were previously under-addressed.

One such critical area is the management of non-human identities—service accounts, application accounts, APIs, and automated scripts that interact with cardholder data environments (CDE) or critical systems.

With the deadline of March 2025 fast approaching, we wrote a blog post to delves into the specific challenges companies face regarding non-human identities in PCI DSS v4.0 and - explores strategies to overcome them.

Will Easton
Will Easton
Identity Security: The problem(s) with federation

Security

/ 30 Sep, 2024

Identity Security: The problem(s) with federation

Federating trust with an identity provider (IdP) is common practice to centralize identity governance.

However, attackers can exploit identity federation to breach organizations or maintain persistence in a system.

This blog post explores common attack vectors against federated identities and effective mitigation strategies.

Vincenzo Iozzo
Vincenzo Iozzo

Ready to start a top-tier security upgrade?

Terms · Privacy · System Status
© 2025 SlashID® Inc. All Rights Reserved.

Products

Identity Protection Identity Management

Resources

Blog Get in touch

We use cookies to improve your experience. Read our cookie policy.