0

I am trying to understand how works various SSO technologies like SAML 2.0, OpenID Connect 1.0.

In general, they work in a similar way providing tokens (XML, JSON) through Identity Provider to Service Provider.

What I don't fully understand is how are these tokens secured so nobody can steal it and use it from different device in order to get authenticated session and impersonate.

Also, how are these tokens stored? Are they stored as a cookie in a browser? If so, would it be possible to steal a token cookie and use it to impersonate somebody?

How can I detect that the token is used in an unauthorised manner?

I am looking for a practical view how are tokens secured and represented when authentication is established or when using as SSO, so authentication is not required by Identity Provider.

2 Answers 2

1

The tokens are secured at multiple level

  1. Transport - Most of the specs recommend SSL (and some mandate it)
  2. Use once - These token are just meant to transfer identity once and then the asserted identity can be attached with local session for further processing. Most of the specs contain safeguards to allow IdP & SP to track the generation and use of token only once.
  3. IdP Trust - The IdP & SP trust mechanism is built in to ensure that only trusted Identity Provider can set an identity at service provider through the protocol.

The checks for MIM and other attacks are built in to each protocol and you can read the RFC/Specs for each of the protocol to see how they stop those attacks.

1

The security of session tokens and session cookies is always an issue you must take into consideration – regardless of the fact if an SSO is used or not. Cookies and session tokens are stored in a browser and protected using various mechanisms. 

  • While they are stored in a browser, they can only be accessed by a specific website due to the Same-Origin Policy. So, if a cookie was set for the test.com, it would not be possible for the attacker.com to gain access to your cookie. However, you should always remember to use a trusted browser (Chrome, Firefox, Edge, Safari) and keep it up to date.

 

  • While the cookies are sent to a server and back, they are protected in transit using an encrypted connection (HTTPS). Even if an attacker is on the same Wi-Fi, they may capture the network traffic, but due to encryption, they will not be able to extract the cookies from it.

 

  • If the application has any vulnerabilities (e.g., Cross-Site Scripting), it might be possible to impersonate the user, access their data, or perform actions from their account, however, this doesn't necessarily mean that the attacker will steal the cookies (and this is not always possible due to the HttpOnly flag) – the attacker might just perform actions directly from JavaScript.

So, stealing tokens is one thing. Another is being able to create a valid token for any user on your own – and this is a whole different story. 

In web applications, we mostly have cookies and JSON Web Tokens (JWT).  

  • A cookie is a random string saved in a database and tied to a specific user. If the entropy of a cookie is not sufficient (or is generated predictably), an attacker might be able to generate a valid cookie and impersonate a user with a specific session. You can find out more about cookies and session management in OWASP Cheat Sheets. If you are interested in the concept of randomness, check out this article about the entropy of UUIDs.
  • A JWT is a stateless token signed cryptographically. It doesn’t need to be saved in a database – it contains all required information, like when it is valid, for whom, and what user it belongs to. You only need to verify the signature. The JWT can be signed using symmetric cryptography with a secret (HMAC) or asymmetric cryptography (RSA). The most obvious attack that would make it possible to impersonate a user is made by gaining access to a secret or private key and being able to create a valid token for any user. You can read more about JWT attacks on PortSwigger Academy.

Considering all the above information, let's now move on to the SSO. 

First, Identity Providers not only provide tokens – they provide confirmation of the user's identity, and providing a token is just a way of doing it. The Identity Provider and the Service Provider have a trusting relationship – which is established during the configuration process by providing proper certificates, secrets, and URLs. 

In SAML, the flow may look as follows: 

  1. A user initiates the login flow at the Service Provider's website.

  2. The Service Provider redirects the user to the Identity Provider with an AuthnRequest ("Hi Identity Provider, could you please authenticate this user for me?").

  3. The Identity Provider authenticates the user, e.g., by asking the user for their login and password. If the provided credentials are correct, the Identity Provider does two things:

    a. Creates a session in the Identity Provider's application, so the next time the user tries to log in using this Identity Provider, they do not have to provide the credentials again (the session might expire or require reauthentication after a specific period, e.g., a week, but if a user tries to log in the next day, it will be transparent for them). 

    b. Creates a signed XML document called SAML Response, which contains the requested information about the user's identity as well as some technical details (when the SAML Response was created, who signed it, how long it is valid, for whom it is valid). Then they send the SAML Response back to the Service Provider. 

  4. The Service Provider verifies the SAML Response by checking the signature against Identity Provider's certificate that the Service Provider has in their configuration. If the SAML Response is valid, the Service Provider can:

    a. Create a new session in their application (using a cookie or a token – however they want). This is the most common way – hence, the SAML Responses are usually valid for 3-5 minutes and are only possible to use once. 

    b. Use the received SAML Response as a session token. However, it would require the SAML Response to be valid longer and allow multiple usage of the response. It is also not very practical, as SAML Responses are quite large compared to a cookie or JWT. 

You can read more about SAML and possible attacks on our blog. 

In OpenID Connect, the most popular flow looks as follows: 

  1. The user initiates the login flow at the Service Provider.

  2. The Service Provider redirects the user to the Identity Provider.

  3. The Identity Provider authenticates the user and creates a session in the Identity Provider's application. Then the Identity Provider redirects the user back to the Service Provider with a code.

  4. The Service Provider receives the code and sends it to the Identity Provider via back channel (not via user’s browser). This connection is done by the application backend, it is encrypted and authenticated (the Service Provider must provide the client_id and client_secret). The Identity Provider checks the code and its validity, they create an id_token and send it back to the Service Provider. The id_token is a JWT – it is a JSON containing user data signed by the Identity Provider, which can be verified cryptographically by the Service Provider.

  5. After receiving the id_token, the Service Provider can now do one of the following:

    a. Use the id_token as a session token. 

    b. Create their own session based on the id_token. This solution is chosen much more often since the applications usually allow other authentication methods (login form, different OIDC providers, magic links etc.), and the applications would like to produce the same session type regardless of the login method.  

It should be noted that if the attacker can steal the code in the OpenID Connect (e.g., due to an open redirect or improper web message configuration), they can use it to authenticate and impersonate the user, even though they never touched any of the session tokens. The PKCE extension helps mitigate some kinds of attacks but is also not bulletproof. 

The last question is how you can detect if a token is used in an unauthorized manner. Here are some tips: 

  • Remember about logging & monitoring.
  • Look out for extensive login attempts, especially failed ones.
  • Verify if the token (SAML Response, OIDC code) has not been used before. Fail and log if it is expired or already been used.
  • Always check if your application is the designated recipient of the token. If not – the token is probably misused.
  • Allow the user to list and end all their sessions.

 

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .