Apr 20, 2022
Clerk
Though each service performs the same function, there are important differences between how Clerk and Stytch manage sessions.
Last week, Stytch
The hardest part about building our API was persisting session tokens with best-practice security, so we were intrigued to see how Stytch handled the same challenge.
When we reviewed their API, though, we found a more lax approach to security than we consider acceptable. This post highlights three ways we found Clerk is more secure than Stytch for session management:
With each concern, we share why it’s important and how Clerk addresses the problem.
It is considered best-practice to set long-lived session cookies as HttpOnly because it helps mitigate XSS attacks
The HttpOnly cookie attribute instructs web browsers not to allow scripts (e.g. JavaScript or VBscript) an ability to access the cookies via the DOM document.cookie object. This session ID protection is mandatory to prevent session ID stealing through XSS attacks.
Despite this, Stytch’s session management API does not set its long-lived session cookies as HttpOnly.
Since stytch.comstytch_session
is not set as HttpOnly:
Further, Stytch’s session management documentation indicates that it sets this cookie client-side via document.cookie
, instead of server-side via a Set-Cookie
header, which would make it impossible to use the HttpOnly option:
Not using the HttpOnly flag means that during an XSS attack, sessions can be hijacked and the attacker can act on behalf of users, even after the vulnerability is patched. Users that visited during the XSS vulnerability must have their sessions revoked.
In contrast, Clerk’s long-lived session cookie is set as HttpOnly. You can verify this by signing up on clerk.com__client
:
Note: Clerk also uses a short-lived session cookie named __session
that is not set as HttpOnly. The JWT in this cookie expires every 60 seconds to mitigate XSS attacks.
Take another look at how the stytch_session
cookie is configured and notice that Domain
is set to .stytch.com:
This is also a configuration that OWASP highlights as dangerous
Setting the Domain attribute to a too permissive value, such as example.com allows an attacker to launch attacks on the session IDs between different hosts and web applications belonging to the same domain, known as cross-subdomain cookies. For example, vulnerabilities in www.example.com might allow an attacker to get access to the session IDs from secure.example.com.
To see a practical example of this concern, we can visit status.stytch.com
A simple dig
command verifies that status.stytch.com is hosted by Instatus:
> dig +nocmd status.stytch.com +noall +answerstatus.stytch.com. 115 IN CNAME cname.instatus.com.cname.instatus.com. 60 IN CNAME cname-china.vercel-dns.com.cname-china.vercel-dns.com. 60 IN A 76.76.21.241cname-china.vercel-dns.com. 60 IN A 76.223.121.106
And, inspecting a request to status.stytch.com confirms the cookie is being delivered to Instatus:
This means that if an attacker gains access to Instatus, they can inspect its HTTP traffic to hijack stytch.com sessions. Phrased more generally, the permissive Domain
configuration for session cookies introduces an attack vector through otherwise-trusted third parties.
Unlike Stytch, Clerk assigns our long-lived session cookies to a subdomain to prevent it from leaking to third parties. In clerk.dev’s case, it’s set to .clerk.clerk.com:
As a result, even though our reference documentation is hosted by Gitbook, Gitbook does not receive this cookie when a user visits reference.clerk.com
Update April 27, 2022: Stytch has partially resolved this issue by allowing developers to configure the "Maximum session duration" in the dashboard. We say "partially" because we still consider the practice of coupling JWT duration to session duration to be dangerous, since it means JWTs used for stateless authentication are not revocable for the full lifetime of the session.
Stytch’s session management API returns JWTs so developers can run stateless authentication. When generating a JWT, developers are asked to set session_duration_minutes
, which is used to determine the JWT’s lifetime:
With stateless authentication, JWT lifetime is the primary variable that impacts how long it takes to revoke a session. Developers cannot revoke existing JWTs, but they can prevent new ones from being issued. As a result, a session is not truly revoked until all existing JWTs have expired. (JWTs can be revoked faster by maintaining a denylist, but then authentication would not be stateless.)
Our concern with Stytch’s implementation is that session_duration_minutes
is configured from the frontend, which cannot be trusted. An attacker can modify the value and generate a JWT that lasts for years – potentially allowing an attack to continue long after the developer believes all JWTs have expired.
This can be demonstrated by signing in on stytch.comsession_duration_minutes
. We were able to generate a session JWT that expires in a year, even though Stytch configures their sessions to last just 7 days.
Clerk also supports JWTs for stateless authentication, but we fixed the lifetime to 60 seconds and use our frontend SDKs to regularly retrieve new ones.
This ensures sessions can be revoked within 60 seconds, which we believe is an essential security feature. To that end, we also provide session revocation UIs as a standard feature in our User Profile component
Clerk is a security company first-and-foremost, but we believe in a future where developers do not need to concern themselves with authentication security. We’ve worked hard to provide robust, best-practice security by default, and we hope this post demonstrates our team’s care and attention to detail on security issues.
While security will always be a challenge, we’re incredibly fortunate to benefit from the researchers and organizations who catalog attack vectors and publish potential resolutions. We will continue to reference their learnings as part of every product and feature we build.
Start completely free for up to 10,000 monthly active users and up to 100 monthly active orgs. No credit card required.
Learn more about our transparent per-user costs to estimate how much your company could save by implementing Clerk.
The latest news and updates from Clerk, sent to your inbox.