supabase / auth

A JWT based API for managing users and issuing JWT tokens
https://supabase.com/docs/guides/auth
MIT License
1.5k stars 366 forks source link

Invitation link should not be useable by automated systems #739

Closed slax57 closed 1 year ago

slax57 commented 2 years ago

Bug report

Describe the bug

We use the generateLink() auth api to generate 'invite' links and send them by email to our customers. We came across the case where the customer has an automated system (probably an anti-spam or anti-malware), which opened all the existing links inside an email prior to delivering it.

Hence, the invitation link was consumed by this system, and had already expired when the customer tried to use it.

I believe such links should forbid being used by automated systems, for instance by checking the user-agent.

To be honest I'm not sure if this is a bug or a feature request, but this seemed critical enough to me to open an issue about it.

To Reproduce

Steps to reproduce the behavior, please provide code snippets or a repository:

  1. Use generateLink() to generate an 'invite' link, like this one: http://localhost:54321/auth/v1/verify?token=1a3f408007230d4143916d714e68be601cba2cb5c023c4e5d490c641&type=invite&redirect_to=http://localhost:3000/register
  2. Paste this link in a Discord/Slack/Whatsapp conversation
  3. Now paste this link in the browser.
  4. Notice we are redirected to http://localhost:3000/register with an error saying the link has expired

Expected behavior

I would have expected the link to be valid when pasted into the browser.

System information

Thanks a lot

chrisb2244 commented 2 years ago

@slax57 - do you know of any way (from the supabase db, logs, GUI/dashboard etc) to check if this is the reason that a link 'expired'? I think I'm hitting the same issue, but it'd be good to confirm this is the cause, and not something else.

For solutions, I've seen these other links referencing the same issue - some suggest workarounds like using the OTP instead and having the user copy/paste a code (which seems like a degradation in UX to me, but better than having them unable to login at all...)

Workaround for single-use auth tokens #7791 Email Links don't pass through enterprise email systems #713 Use invite link twice. #6004 Email password reset link is invalid for certain emails supabase/supabase-js#342

slax57 commented 2 years ago

@chrisb2244 No I don't, sorry. I had the intuition it might be this based on customer feedback, then confirmed it by doing a real-world test with Discord.

Thanks for the links btw, makes me realize this issue has been raised already (even if not as gh issues).

Our team chose to workaround this by creating an indirection table to store the link and an intermediate screen requiring the user to click on a button to actually be redirected to the supabase link.

chrisb2244 commented 2 years ago

Would you imagine that such automated systems would run with window defined? (as in, in a browser?) If not, perhaps a page (on the user side) that takes the token as a query/hash parameter and then runs something like (pseudo, untested code):


if (typeof window !== 'undefined') {
   const realLink = getAppropriateSupabaseLink(req);
   fetch(realLink, { method: 'POST' }) // not sure if this should be post or get, 
   // and also probably the supabase verify endpoint might be appropriate, 
   // and handle the function described by 'getAppropriateSupabaseLink' or similar...
} else {
   // Do nothing because this is running in some email-scanning system or automated whatever?
}
EskelCz commented 1 year ago

Or maybe don't consume the link after the first use, allow two uses.

hf commented 1 year ago

Duplicate of #713.