Comment by singron

1 day ago

> Server actions are public, unauthenticated routes

Why can't they be authenticated? That seems like the obvious fix. Otherwise how you are handing out the correct customer_id unless you authenticate somehow?

This scheme also complicates API key rotation, although you can work around it by trying to decrypt with both the old and new key if you use e.g. authenticated encryption.

This also has no mechanism for expiration (besides API key rotation). If you add an expiration time and sign it, then you essentially created an authentication token that you use as the customer_id.

Maybe we didn't phrase it as well as we should've. We meant to say API routes in general are public, and so the server actions could be called by anyone.

Authentication is definitely possible, but we were trying to brainstorm a way where users could have protected routes with as little set up as possible, the ideal being they just pass in customerId into a Provider component

We also did think about things like registering an auth function but felt that being able to just pass in customerId would be a magical experience!

Definitely acknowledge that the current mechanism has flaws though -- it's really more of an experiment at the moment, and if it does indeed become very popular with users we would implement auth mechanisms like JWT and what not -- though that would kinda be reinventing the wheel

  • The current mechanism has security flaws that are hiding because of SSR. Try to implement the same flow in pure-vanilla-js and you'll realize that you're hitting replay attacks instantly. This is the same vulnerability that companies which try to "hash the password on the client side to protect it" face - they've merely transformed the password to a different one (the hashed one) which has the exact same semantics as the original password for an attacker.

    Your encrypted customer ID has the exact same semantics as the original customer ID for an attacker, and is insecure.