Launch HN: SuperTokens (YC S20) – Securely manage session tokens

84 points by advaitruia ↗ HN
Hi everyone! My name is Advait and I co-founded SuperTokens along with @rishabhpoddar (https://supertokens.io/). SuperTokens helps companies securely manage their session tokens, saving developer time and preventing identity theft.

We started SuperTokens 1.5 years ago when we were building a consumer app and wanted our users to be logged in for a long time in a secure way. When it came to managing user sessions, there was a lot of ambiguity. We read many forums (Reddit, Stackoverflow) and blogs, and found that developers were arguing about best practices, such as using local storage vs cookies, implementing JWTs, etc. We had to do a lot of the first principles thinking ourselves to understand the tradeoffs. Around the same time, Facebook, Docker, Gitlab, Youtube, Uber were in the news for session vulnerabilities.

Stealing a user’s session allows you to access their account as if you had their username and password. Hence being able to mitigate against this is important. We’ve audited companies and found large session vulnerabilities that they were not aware of. For a YC company, we were able to pull information on users that we shouldn’t have had access to.

Through our research, we built something internally and decided to write a blog post [1] explaining how our system works. While SuperTokens is not currently open source, you can see the original codebase on Github [2].

Building a good solution for sessions requires a lot of specialised knowledge and time that could otherwise be spent on building your core business logic. Detecting session theft reliably is difficult. There are multiple race conditions, edge cases and network issues that need to be thought about. In fact, one of our libraries that solves a difficult race condition has 100K downloads / week and is even used by Auth0 [3]

SuperToken mitigates against all session attacks (XSS, CSRF, etc) by implementing best practices. For a full list of types of attacks with real life examples please see [4]. However, it is not possible to mitigate against all attacks (for eg: social engineering) and hence, SuperTokens is also able to detect session theft. We use rotating refresh tokens as per the official OAuth specifications in RFC 6819 [5]. Auth0 has also started offering this, but due to their setup, they cannot use httpOnly cookies to store these tokens and this goes against popular compliance recommendations.

Besides security, SuperTokens also offers improved API performance and developer convenience. For clustered and distributed environments, session verification for each API takes < 1 millisecond. You can get a user’s ID and access role without any database lookup. SuperTokens can be implemented in 15 minutes, provides a simple API and has clear documentation. We abstract away complexities of token management by providing frontend and backend SDKs.

In the coming months we plan to offer Access Control, Internal Auth between services and for internal tools (i.e. recent Twitter hack was through unauthorized access to an internal tool), and more! We're still experimenting with pricing, so you won't find this on our website, but we'd love to hear your thoughts about it.

Thank you for reading! We’d love to hear what this community specifically has to say and if you have any experience dealing with this. We’d appreciate any feedback!

----------

Footnotes:

[1] - Blog post: https://medium.com/hackernoon/all-you-need-to-know-about-use...

[2] - Github: https://github.com/supertokens/supertokens-core

[3] - Library used by Auth0: https://www.npmjs.com/p...

61 comments

[ 2.3 ms ] story [ 114 ms ] thread
I don't see any kind of compliance, code audit, or SLA to back up the kind of claims your landing page makes.

Also, maybe it's just me, but your landing page is very slow and laggy, and my browser hung a bit while navigating around.

Thanks for letting us know! We use Cloudflare and had to purge the cache today cause of some changes.. Is it laggy while scrolling any specific page? Or only when switching pages?

About compliance & code audits, those are being planned. We will have code auditing done in a few weeks from now. But yea, I understand your point. Thanks!

Both, the initial page load and getting to the carousel is pretty sluggish.
> While SuperTokens is not currently open source...

Might want to update your Twitter, then?

@supertokensio The most secure solution for user session management... We're open source and easy to implement.

Thanks for pointing that out :) But we also are going to release an open source version soon (if not make the whole thing open source).

Also, for now, we have removed that claim from our Twitter.

There's this: https://github.com/blitz-js/blitz/blob/724c6921da1646a35625b...

It's neither the old open source version of supertokens, which is deprecated, or the new version of supertokens, but is in between.

Yup. For blitz, there is a default session management solution that's essentially based on a long lived, opaque access token. There is also going to be one which is what SuperTokens is. Either using SuperTokens directly, or an implementation of that in Blitz itself.
Is this really a problem that needs solving?

Generate a secret, hash it, and store it in your database. Set the secret as a cookie in the client. On every request, hash the cookie value on your server and compare it to your DB values.

It seems like very little effort to implement this yourself in a way that doesn't involve completely trusting a different company.

We believe that session attacks are going to increase in the future given that login is becoming more secure (passwordless, hardware keys etc etc)..

As such, for long lived sessions, just having one token makes that the weakest link in that user's security. That's why we believe that this is a problem worth solving = minimising security risk.

The method you suggested is one that you understand and can build. A lot of developers do not know much about session security, but still want security.

Thanks for your feedback though. It's true that not all apps will want this level of security. We understand that.

> As such, for long lived sessions, just having one token makes that the weakest link in that user's security. That's why we believe that this is a problem worth solving = minimising security risk.

Can you help me understand the specific attacks you're trying to mitigate that aren't already solved by a combination of best practices implemented by current engineering frameworks (session management across most fairly mature tech stacks) and browser controls (e.g. samesite cookies)?

for example, spammers and hackers use the same session id across different devices. this technique can help avoiding rate limits and also allow using it programmatically. it is nice to be able detect such things. I work for e-mail provider and spammers are becomming increasingly sophosticated and are finding new ways to exploit such security holes
Thanks for your comment. There are a couple of points for this answer:

-> Short lived sessions:

A lot of the guidelines (OWASP, NIST, industry compliances) recommend having short inactivity timeouts, and "in session", frequent reauths. Those have clear UX problems, but for apps that are OK with those problems, implementing such mechanisms is good enough, security wise! Most existing libraries easily allow you to build inactive timeouts, but building the frequent "in session" reauth, can be tricky: detecting when last auth happened, saving state of an app between reauths & regenerating session tokens after reauth. Due to these issues, sites end up implementing sessions from scratch and mostly always make some mistake. For example, I have seen banks store session tokens in the page HTML as opposed to HttpOnly cookies. One of our aim is to make it very simple to implement all these best practices recommended by OWASP, NIST, and industry compliances.

-> Long lived sessions:

For all other apps that want to keep their users logged in for longer, frameworks only enable the use of one long lived session token (alive for weeks or months). In this case, if that token is compromised, the user's account is compromised for a long time. Theft of token is possible in multiple ways, even if using httpOnly cookies: https://supertokens.io/pdf/attackshomepagev2

For some people, this risk matters. For them, they want to achieve long lived sessions + reduce the risks of theft. For them, using the existing framework solution is not good enough.

-> Functionality:

There are a lot of functionality that can be required on top of sessions:

- Syncing session data across devices

- Getting all active sessions of a user

- Setting different inactivity timeouts based on a user's role

- Revoking access to a specific device

- Logging in as a user (for support team)

Most of these and perhaps more are required for "serious" apps. Most frameworks do not allow to easily implement all of the above. As result, devs implement their own session solution, and make mistakes.

-> Other considerations:

For many devs, JWT is the goto for sessions (free scalability). Since most frameworks do not choose JWTs for sessions (in their inbuilt solution), devs choose to use something else and make mistakes like storing the JWTs in localstorage.

Incorrectly configuring sessions in these frameworks can also cause issues. For example, during development, secure attribute for cookies is usually set to false. Sometimes, devs forget to set them to true for production use. Another example is that during development, your API is on api.example.com, but your site is on localhost. For this to work, you set sameSite to none, and forget to switch it to lax for production. SuperTokens aims to be very opinionated in order to prevent such mistakes (...catching these errors is not yet implemented though, but soon).

-> Conclusion:

Overall, the in built sessions in the frameworks are good for many apps. However, for those "serious" or complex apps, people end up building something custom (and that's a lot of companies ~ 50% of our YC batch built a custom solution or used JWTs despite of inbuilt sessions in their framework). Our solution is for such people.

Got it. So it's not so much implementing known-good session management as it is implementing session management edge cases that allow for improved usability without significant compromises in security.

Is that a fair summary?

I wouldn't consider them as "edge cases" per say. It's an end to end session management solution that aims to be secure and covers all needs for simple and complex apps.
I suppose that depends on perspective. An argument can be made that a subset of the 50% of your YC batch are doing session management wrong if they're building a new app and feel they have to home-grow a solution.

That said, considering the standard guidance around session management is "don't do it yourself," then by delegating to you, your customers also distribute that risk to you and gain some amount of indemnity as a result. So using SuperTokens would be a valid risk management strategy provided firms are:

1. fine with what's essentially indefinite vendor lock-in (at least until they ditch the software platform they've written that relies on SuperTokens), and

2. doing their diligence around your security controls.

And if they've met those conditions and feel that paid session management gives them extra UX cases that they don't have available to them for building out their solution, then more power to them.

The only implicit guidance in all of this that I'll make explicit is to make sure you're investing in the security of your platform considering it's the product you're selling. Many of your customers who would consider buying into this service would do so knowing that it essentially comes with some amount of indemnification regardless of whether or not you disclaim it.

Final thought: it'll help you a lot if you clearly define a Shared Responsibility Model that outlines the security responsibilities SuperTokens will own v. the security responsibilities the implementing customer will own. What'll help even further is if you can then cement your Shared Responsibility Model and prove the controls you claim to have with e.g. a SOC2 type 2 that defines Complementary User Entity Controls.

There's a market for what you're offering, but you'll have to be strategic about capitalizing on it and not potentially becoming a victim of your own success as you acquire customers who themselves will be the targets of attacks- ergo attacks against your platform.

Noted. Thank you for the suggestions. I may reach out to you sometime in the future :)
Wish you the best in any case :)
Small typo in your pdf:

> Storing only the hased versions of session tokens

Additionally, OWASP publishes so many guides on session management, along with checklists, to make it easy to see state of the art and best practices in this domain.
They do! But most open source solutions to not follow them, which means most apps do not follow them, and for those who care about OWASP session guidelines, need to mostly build their own system.
I'm not going to speak for the company or their solution, but yes it is a serious problem. The token itself isn't the hard part as you pointed out, it's the full life cycle management of it and the security analysis is. Detecting and acting on session hijacking is hard to do right. It can get very complicated as well if your system needs to enforce things like non-concurrent logins, etc.

But I'm glad the company offers a self-hosted version rather than being forced to rely on their managed service (that was the first thing I looked at). I haven't dug into it at all and am taking at face value that their self-hosted daemon doesn't have any required real-time connections to their systems, but that would be a deal killer as well.

Thank you!! We use rotating refresh tokens to detect session theft reliably.
I'm not entirely sure I'm understanding the terminology you're using.

Are you talking about OAuth2 tokens (i.e. https://tools.ietf.org/html/rfc6819#section-5.2.2.3), or are you talking about browser cookies?

In both cases, rotation strikes me as being of limited (though nonzero) value. While rotation (and invalidation of the previous token) can be used to prevent long-lived concurrent use of cloned tokens, there's a good chance an attacker can ensure that they are the ones who get the "new" token.

As a result, the user--the legitimate OAuth client or browser--would be left with the now-invalidated token, and will be logged out. The most likely result of which--depending on application design choices--is that the user simply logs in again! You now have two sessions, one of which is solely owned by an attacker, and one of which is solely owned by a user!

(There are cases where this is still valuable: if you enforce "only one session globally" per user, for example, or if you use the presentation of an "invalidated" token as indicative of theft. But both are application design choices that will commonly be inappropriate.)

At the extreme, of course, if your threat model is local malware, UXSS, etc, an attacker can just do a "person in the browser" attack, in which no token copying happens.

I'm not sure why I'm bothering to write all of this. Call it free consulting? ;)

My point is really that the threat model needs to be clearly stated and, for some threat models (including some which are featured in case studies on your website), this approach may be largely ineffective.

> It seems like very little effort to implement this yourself in a way that doesn't involve completely trusting a different company.

What about cookie configuration (secure, httpOnly, samesite), signing, expiration, session management, etc? Getting and setting the cookie value are the easy part.

For someone entrenched in appsec, most of these are fairly easy. But most developers are not entrenched in appsec. For proof of this, look at the popularity of Auth0.

Thanks! And more proof for this comment is the sheer number of questions / blog posts written about sessions and JWTs almost weekly on reddit, HN, stackoverflow etc..

If this was very simple to solve, securely, those questions, blog posts would not exist.

I think the problem is that websites today don't have enough single points of failure or maybe that websites today have too few third parties with access to private information.

Something like that.

It reminds me of the fad to get people to use "Javascript CDNs" that are "free" because they track your users with cookies.

Good luck guys! Do it right and keep moving forward, it's a problem that does need to be solved. Just make sure it can work behind a corp firewall without hooks back to your servers ;-)
Can you talk a bit about the tech stack behind this? I see <1ms API responses which is very impressive, curious to hear more about the implementation.
Sure! Briefly, we use JWT access tokens which are used for session verification. JWTs can be verified using just a secret key which can be stored in memory. Hence, no network calls = < 1MS latency.

However, there are issues with using just a JWT, like inability to revoke them or bottlenecking all user security on one secret key. To solve those and other issues, we use rotating refresh tokens. More about this here: https://supertokens.io/blog/are-you-using-jwts-for-user-sess...

Congrats on launching!

If I understand correctly, you're having me integrate a library on my backend that manages session cookies.

You've implemented refresh tokens and that seems to be one of your major selling points, but I'm confused what benefit that provides?

I thought the use case for refresh tokens in OAuth was that the user can revoke access from the OAuth provider side. But since the user can't go to SuperTokens and revoke their session, isn't the refresh token functionality superfluous?

Thanks! The benefits we provide are session security and convenience (not having to know or think about tokens and session management).

We don't use normal refresh tokens. We use one time use refresh tokens. This allows to detect token theft in a reliable way for long lived sessions (https://tools.ietf.org/html/draft-ietf-oauth-browser-based-a...).

Also, OAuth is different to session management in that OAuth is for delegation purposes, whilst "a session" can be used to maintain authentication between your own frontend and backend.

In terms of revocation of sessions, our SDK provides functions that can be used to revoke sessions. Soon, we will be making a dashboard that can be used to do the same (and other things)

Thanks for your response!

I'm still a bit confused why you're referencing OAuth here and in the launch announcement while also saying "OAuth is different to session management"

Why have you chosen to use OAuth solutions if you're not solving an OAuth problem? How are you sure it's still the right solution? I see some overlap but it's not obvious to me that OAuth methodologies should be applied here.

Technically, you do not need to exactly follow OAuth methodology for sessions. You are right. However, there is one common problem with sessions and OAuth, which is token theft.

In order to detect token theft, we use the general principle of changing tokens on each use. So theoretically, we can use one random string token, that changes on each use and solve the problem in case of sessions.

The problem with that is that it's not scalable since for any request that changes tokens, we need to synchronise calls to that request (https://supertokens.io/blog/the-best-way-to-securely-manage-...).

In order to make things scalable & have this security benefit, we use two tokens. One that doesn't change, and one that is used rarely, but changes... This starts to look like OAuth now.

Pushing it further, we can name those tokens access and refresh tokens. So while OAuth and sessions are different, we can pick specific concepts from OAuth and apply them to sessions.

Your pricing is pretty hard to find, had to go to documentation -> scroll to the bottom and it's in the right hand corner. Then when I click on it, there is no pricing on that page.
I understand that this is annoying. The reason we have it that way is cause we are experimenting with pricing on a per user basis - it's like the "contact us" pricing plan for other SaaS products.

Soon, we plan on standardising pricing based on our pricing experiments. Thanks for the feedback!

Cool product and I can see myself using it. What's the difference between the non-pro and the pro licence?
Thanks! As of now, there is only one version - the pro version. We may add an open source version soon. If we do, it will be clearly mentioned on our site along with what the feature differences between the non-pro and pro versions are.
> We're still experimenting with pricing, so you won't find this on our website, ...
AD: I authored a solution to the revocation of tokens[1] for JWT and even verified the solution through TLA+. It uses a monotonic counter as a claim per JWT, you can revoke X active sessions behind the last issued, you can also use time to do temporal permission inflating (sudo... etc).

What sort of verification have you done on your solutions? What are the down falls of your solution?

[1] - https://github.com/endiangroup/compandauth

Sounds interesting! I'll have a look at your library. Our solution takes relevant aspects of the OAuth specs. Specifically the idea of using rotating refresh tokens to detect session theft.

That being said, we have not had any formal verification. We plan on doing an outside code review / audit from a reputable 3rd party in the coming weeks.

Two question for you: - In your solution, I assume there is one JWT per logged in user. If I want to revoke one user's session specifically (without affecting other users who have a similar count), how would I do that? - When would I want to revoke all sessions before some count X?

Apologies if I have misunderstood how your lib works.

Good luck with the audit, the solution sounds interesting on the surface!

Ah I think you've slightly misunderstood, there is a 'counter' per entity, each user has their own separate counter so when you are revoking it is only relevant to sessions related to that users account. This would fall under your database lookup version of JWT management, it's centralised but in the smallest way possible.

That might clear up your second question, you'd want to revoke all sessions like I'd want to 'Log out all other active sessions', logging in to my Spotify on my friends computer last week, and my sisters the week before, I want to log them ALL out.

I see. Thanks for the clarification.

So when you are verifying an incoming JWT, don't you need to check what the allowed counter is for that session? If yes, then doesn't that require a database / cache lookup for each verification? And if it does, then how are you able to get super fast session verification?

Yes absolutely, as I stated in the comment before. The super fast verification is once you've done the DB lookup and do the actual comparing (as it's just int64 comparisons). CAA is intended as a set of primitives to be built on top of.

As I understand ST is in effect making the client act as the cache by giving them a refresh token (RT), you delay having to do a central DB lookup until the AT expires and RT is used... You could do the same with CAA, check the DB every X interval (30s) instead of every request, the security implications would be the same (some period of time that no matter who is using the token it will work) as I understand?

From what I've read Theft Protection is a matter of detecting reuse of RT (as I've understood), again with CAA and using the above, you could track each periodic "check" against the master with another counter and embed into the token, if you see a tracking number < or > what you've seen then a Theft has occurred. Would that be the same as ST?

Yea! Absolutely. Both our solutions follow the same fundamental idea of changing tokens to detect theft. That being said, there are edge cases that need to be considered when detecting token theft such that there are no false positives: https://youtu.be/6Vzit514kZY?t=747.

The video about describes 2 edge cases specific to our flow, but I maybe they also apply to your solution?

This is great! Any plans to support Elixir/Phoenix anytime soon? Don't see it in the dropdown in your website :(
Thank you :)

We can add that to our roadmap. We are also happy to prioritise depending on your use case and commitment! Do reach out to us via email (team@supertokens.io)

I don't wanna hijack his thread, but I'm a small contributor to a great open source project library called AccountsJS, which seems pretty similar to this, AFAIK. and it's really modular/flexible on whatever you want to implement it with!

You can use it both with REST/GraphQL, and any frontend you may like.

Also supports Oauth like Twitter, FB, Google, Insta, etc...

Has 2FA. MFA on the works...

Anyway if it piqued your interest here are some links: http://accountsjs.com/ Repo in GH: https://github.com/accounts-js/accounts

> I don't wanna hijack his thread...

But you did :) accountjs looks great! Another related hands-off do-it-all solution that I like is https://userbase.com.

How do refresh tokens work in the presence of concurrent requests from multiple tabs? I don't see how two tabs could synchronize their access in a way that won't lead to the possibility of one tab thinking it has been logged out. I guess you can try and paper of these issues with JS but without client side JS you are completely lost.
Yea! That's why we have a frontend SDK that solves for issues like these. Our SDK uses a library called browser-tabs-lock which provides locking across tabs (https://www.npmjs.com/package/browser-tabs-lock). So essentially, whenever a refresh call is made, we synchronise those requests.

This library is written by us to solve for the exact problem you mentioned! It's also being used by Auth0

Congrats on the launch!

We're building stuff in a similar space! Would be cool to chat and swap ideas: we're https://www.osohq.com, I'm sam@ the same domain.

Awesome!! Your site looks really clean! Will reach out!
This really isn't a problem that needs solving? Much less paying some random company to have access to all your user data.
Not all apps will want to have a good level of session security (as of today). But there are enough that do.

We have a self hosted version that uses your own db to store tokens. So you don't need to give us any "user data".

I am using FaunaDB for a side project and your product would be a very good fit to work with their tech.

They have a built-in authentication in their distributed database, but not session management. A lot of people is starting to build things with FaunaDB and struggling with auth. In their Slack they even had to open a channel only for authentication doubts.

So if you are looking for a niche, the FaunaDB integration could be a good shot.

Actually yes! We are already working on providing session management for FaunaDB users. Using us, you can easily get a FaunaDB token for a user on your backend and frontend. We take care of all the heavy lifting of creating those tokens and making sure they are alive (and of course, providing session management).

We should have something out in a few weeks from now!

Can I ask how this fits with the YC thinking that startups should have unicorn potential?
We are in the authentication space. Sessions is a way to get into the space.