18 October, 2023
Vulnerability disclosure: Session fixation in Auth0
This blog post is written by Laban Sköllermark, pentester and IT security consultant at Sentor, a part of Accenture Security.
At Sentor we often see vulnerabilities in authentication, authorization and session management during pentests of our clients’ web applications when they have implemented it themselves. The general recommendation in the industry is to use standard authentication and authorization implementations in frameworks rather than implementing everything yourself. The reason for this is that it is very easy to make mistakes. This is like the popular and widely accepted recommendation “don’t roll your own crypto”.
But there can be flaws in any system – even the big and widespread solutions for authentication and authorization. There are a lot of terms with abbreviations in this area: Identity Access Management (IAM) / Identity Provider (IdP) / IdP as a Service (IdPaaS) / Identity as a Service (IDaaS). This is the story of when I discovered a session fixation vulnerability in a non-standard configuration of Auth0’s product which was used by a client of Sentor.
The impact of the vulnerability is that an attacker could hijack a victim's account if there was a Cross-Site Scripting (XSS) vulnerability in another subdomain of the application using Auth0, or on any *.auth0.com subdomain, and the victim could be lured to that site. Another possibility for exploitation was if the attacker could gain a Meddler-in-The-Middle (MiTM) position on a network to manipulate plaintext HTTP traffic for a victim.
The 6th of September 2023, Auth0 said that they have mitigated the vulnerability.
About Auth0 by Okta
Auth0 is quite well-known in the web application sphere. They started in 2013 and offered a Software as a Service (SaaS) for identity management. They have published a lot of open-source Software Development Kits (SDKs) on GitHub, like the java-jwt library for signing and verifying JSON Web Tokens (JWTs) in Java. They are also the ones behind the site jwt.io, which is mainly for decoding and verifying JWTs. You can also use the site to experiment with signing.
Auth0 was acquired by Okta (the process started in 2021 and was completed in 2022). Their solution, which has been called just “Auth0” previously, is becoming Okta Customer Identity Cloud, but I will use “Auth0” throughout this blog post.
Auth0 can be used for federated login using for instance Microsoft, Google and GitHub. When you set up your tenant, you can let Auth0 be the directory with users and passwords.
The login page above can be customized both in terms of settings and its design. You can redirect your users to log in on your Auth0 tenant at [example].eu.auth0.com
or you can include the login box in your web application with Auth0’s JavaScript. You can also implement your own login logic by using Auth0’s API. If the domain presenting the login form is not the Auth0 tenant ([example].eu.auth0.com
), an Auth0 non-default feature called Cross Origin Authentication must be enabled. Modern browsers do not let you post form data across domains, such as from app.example.com
to [example].eu.auth0.com
, but this can be solved by enabling the Auth0 feature Custom Domain which lets you point your subdomain login.example.com
to Auth0. In this way, your application at app.example.com
is allowed to post form data to it (login.example.com
) because it is under the same domain.
Vulnerability type: Session fixation
The American not-for-profit organization MITRE is publishing the Common Weakness Enumeration (CWE) list with software and hardware weakness types. The weakness session fixation has identifier CWE-384 and has the following description:
Authenticating a user, or otherwise establishing a new user session, without invalidating any existing session identifier gives an attacker the opportunity to steal authenticated sessions.
Such a scenario is commonly observed when:
- A web application authenticates a user without first invalidating the existing session, thereby continuing to use the session already associated with the user.
- An attacker is able to force a known session identifier on a user so that, once the user authenticates, the attacker has access to the authenticated session.
- The application or container uses predictable session identifiers. In the generic exploit of session fixation vulnerabilities, an attacker creates a new session on a web application and records the associated session identifier. The attacker then causes the victim to associate, and possibly authenticate, against the server using that session identifier, giving the attacker access to the user's account through the active session.
Finding session fixation in Auth0
During a web application web test for one of Sentor’s clients, which used Auth0 for authentication, I found a session fixation vulnerability. I reported it to Auth0 and below is the (second, more detailed) report I sent them, but with a few edits on spelling, formatting and some clarifications. Screenshots of Auth0 configuration pages are included in the blog post to make it easier to follow, especially for people not having set up Auth0 tenants themselves.
I'm a pentester and I've found a session fixation vulnerability under some Auth0 non-standard configuration. I've found the problem when pentesting a customer of yours, but I have reproduced the problem in a trial tenant as well. The name of your customer is included in the report since they have allowed me (but the name is not included in this blog post).
The technical details are included below. The Vulnerability Rating Taxonomy (VRT) classification is according to Bugcrowd’s definitions.
I wish to know if you consider my finding a security vulnerability, whether you intend to patch it and if that can be done within 90 days.
This bug is subject to a 90-day disclosure deadline. After 90 days elapses, the bug report will become visible to the public.
Cross Origin Authentication has a session fixation vulnerability, at least when using Username-Password-Authentication. Once set, the value of the auth0
(and auth0_compat
) cookie does not change when a different user is authenticated, unless the application calls an Auth0 logout endpoint.
If an Auth0 customer is using a Custom Domain such as login.sentorsecurity.com
(just an example), then the session fixation vulnerability can be exploited by an attacker if either:
a) there is a Cross-Site Scripting (XSS) problem at any subdomain (*.sentorsecurity.com
) so that an auth0
cookie can be set (fixated) when a victim is using the site
b) some subdomain is not covered by HTTP Strict Transport Security (HSTS) and an attacker can achieve a Meddler-in-The-Middle (MiTM) position and inject an unencrypted HTTP response header Set-Cookie: auth0=…; domain=sentorsecurity.com; path=/; max-age=31536000; samesite=none;
when a victim is visiting the page using plaintext HTTP
If the Auth0 customer is not using a Custom Domain and instead use for instance sentorsecurity.eu.auth0.com
, then the session fixation vulnerability can be exploited by an attacker if either:
a) there is an XSS problem at any Auth0 subdomain (*.auth0.com
) so that an auth0
cookie can be set (fixated) when a victim is using the site
b) the victim has not visited the Auth0 documentation (!). The site https://auth0.com/ has HSTS but no includeSubDomains
. The pages under https://auth0.com/docs/ set includeSubDomains
in their HSTS policy, however. The problem can be exploited if the victim can be tricked into making a request to a "new" subdomain (which the victim has not already visited), for instance whatever-blablabla.eu.auth0.com
, and an attacker can achieve a Meddler-in-The-Middle (MiTM) position and inject an unencrypted HTTP response header Set-Cookie: auth0=…; domain=auth0.com; path=/; max-age=31536000; samesite=none;
when a victim is visiting the page using plaintext HTTP.
A successful attack is relying on which browser the victim has. Newer Mozilla Firefox versions restrict cross-site cookies in the default setting in a way that makes it ignore the setting of some cookies. In Google Chrome it worked out of the box, however. To reproduce in Firefox, you might need to adjust (or completely remove) the blocking of cookies in Enhanced Tracking Protection under Settings -> Privacy & Security. I used Firefox 102.12.0esr (64-bit) under Kali Linux.
Steps to reproduce in a trial tenant follow.
The victim tenant is a trial tenant at dev-nn41qmsm56z6ffw2.us.auth0.com
, which has a Single-Page Application (SPA) with client ID Vz0wYTtjdWPbQ47A2xLtoHtZg5qvv3W7
.
1) The attacker either has some account themselves (such as if user registration is allowed) or can get a valid auth0
cookie from another dev tenant (in the same region might be a requirement). I signed up for dev-j34aiglnx8fz83sc.us.auth0.com
just to get such a cookie after authenticating as an added user. The cookie must be created by a Cross Origin Authentication endpoint (/co/…
) - those cookies are shorter. My sample attacker cookie: auth0=s%3AWMzbX1-276EkqevDqrm7_hFgHjypP9kx.dSaHPX9Ciuy79QomXaEmL%2Bv2R5kfo0jwjjWFawapXxs
2) Get a MiTM position or find an XSS vulnerability to inject the cookie in a victim's browser. I've simulated this by adding 127.0.0.1 mitm-or-xss.us.auth0.com
to my /etc/hosts
file and serving the following http://mitm-or-xss.us.auth0.com:8082/index.html
and making a victim access it:
3) Wait for the victim to login to the victim tenant. I used https://test21.sentorlab.se/
to host a minimal SPA using Auth0 Lock to act as the victim application. It consists of just an index.html file:
4) The victim logs in with ts21+auth0-user1@sentorlab.se
which is a Username-Password-Authentication user in the victim tenant (dev-nn41qmsm56z6ffw2.us.auth0.com
).
The HTTP request and response are shown below where it's clear that the auth0
cookie value remains on successful login. The rest of the requests to exchange an id_token
are not included. (In this blog post, irrelevant data has been replaced with […]
and JSON data has been prettified for readability.)
5) The attacker, who knows the unchanged value of the auth0
cookie, can now make a single request to get a JWT for the victim. This works multiple times, as long as the session is valid.
Decoded id_token
(JWT):
Recommendations
The following recommendations to mitigate the vulnerability were sent to Auth0:
1) Set a new value of the cookie auth0
(and auth0_compat
) on every successful login, even when Cross Origin Authentication is enabled (on /co/
endpoints).
Status: Auth0 reported this as fixed the 6th of September 2023. I confirmed the fix the 17th of October.
2) Submit auth0.com
to the HSTS preload list so that even the first request a visitor makes to any subdomain is using HTTPS. The includeSubDomains
directive should not rely on documentation being visited.
Status: Not done.
3) Consider adding the cookie prefix __Host
- to session cookies, e.g. __Host-auth0
so that the cookie cannot be set over unencrypted HTTP communication or from another subdomain. See MDN Web Docs on cookie prefixes.
Status: Not done.
The fix
The 17th of October I confirmed that the issue was fixed, on request by Auth0. Their /co/authenticate
endpoint now generates a new session ID when authenticating as another user. If a valid session is supplied in the auth0 cookie on authentication and that session was created for the same user, the session ID remains the same. That is not best practice but makes it impossible for an attacker to fixate a session without having compromised the victim once.
Previous Auth0 session fixation vulnerabilities
This is not the first time session fixation problems have been discovered in Auth0 products. In 2018, Kévin Chalet found one in some Auth0 Software Development Kits (SDKs) and in 2021 Auth0 disclosed one (CVE-2021-41246) in express-openid-connect. It’s a bit ironic that they included session fixation in their blog post What Is Broken Authentication? in 2020, but of course nobody is immune to creating security problems.
Timeline
All times are given in Central European Summer Time (CEST, UTC+02:00).
2023-JUN | Found the session fixation vulnerability during a pentest of a Sentor customer’s web application, which used Auth0 for authentication |
2023-JUL-10 (Day 0) | Sent the first vulnerability to security@auth0.com, GPG encrypted to their expired PGP key |
2023-JUL-11 (Day 1) | Auth0’s security team instructed me to use their Bugcrowd form at their Responsible Disclosure Program page |
2023-JUL-11 (Day 1) | I explained that I could not accept Bugcrowd’s terms and asked if they managed to decrypt the attached GPG encrypted file despite their GPG key had expired |
2023-JUL-21 (Day 11) | Sent an improved vulnerability description encrypted with Auth0’s new PGP key (from their security.txt file) |
2023-JUL-21 (Day 11) | Auth0’s security team acknowledged successful decryption of both reports, told me that they thought it was a valid finding, that they managed to reproduce the problem and that they will inform me when the issue is fixed |
2023-SEP-06 (Day 58) | Auth0 informed me that the issue was fixed |
2023-SEP-26 (Day 78) | Auth0 reached out and asked for a preview of my blog post |
2023-SEP-27 (Day 79) | I responded that I had not started writing but promised to send a preview before publication |
2023-OCT-08 (Day 90) | 90 days had passed since sending the first vulnerability report to Auth0 |
2023-OCT-10 (Day 92) | A draft of this blog post was sent to Auth0 |
2023-OCT-16 (Day 98) | Auth0 responded that their team is looking over the disclosure and asked me to confirm the fix (re-test) and wanted to include a statement to the blog post |
2023-OCT-17 (Day 99) | I confirmed Auth0’s fix of this session fixation vulnerability and asked what statement Auth0 wanted to include. They intended to get back in 24 hours. |
2023-OCT-18 (Day 100) | Publication of this blog post |
What about you?
Do you want to find out if your application is vulnerable to this or other security problems? Let us test it!
Do you want to help customers find these kinds of vulnerabilities? Join our team of pentesters in Sweden!