Issues I’ve encountered building an app with magic links:
1. Include a fallback sign-in code in your magic link, in case the user needs to log in on a device where accessing their email isn’t practical.
2. Make sure the sign-in link can handle email clients that open links automatically to generate preview screenshots.
3. Ensure the sign-in link works with email clients that use an in-app browser instead of the user’s preferred browser. For example, an iOS user might prefer Firefox mobile, but their email client may force the link to open in an in-app browser based on Safari.
We went to a lot of trouble to make our magic link implementation work with anti-phishing software, corp link checkers and more. https://github.com/FusionAuth/fusionauth-issues/issues/629 documents some of the struggle.
I think that a link to a page where you enter a one time code gets around a lot of these issues.
I arrived at the same conclusion after going through the steps and seeing that some corporate systems mark the login link as malicious, and there’s nothing I can do about it.
Sending a code goes around a lot of issues.
Also: Safari can autofill codes from both email and text messages on macOS and iOS. It then automatically deletes the message too.
https://www.webnots.com/how-to-autofill-verification-codes-i...
Why not just support a password?
Only having magic links gets you a load of stuff for free,
Higher level of security than just user+pass (w/ forgot password)
Email verification
Lifecycle management - in a SAAS when a user no longer has a corporate email, they can defacto not log in, wheras with a user+pass you need to remember to remove their account manually on each SAAS or have integration with your AD (for example)
It’s not a higher level of security than password-based authentication. Why do you state that?
One-time email verification is not the same as security model as magic links. Magic links require instant access. Many security sensitive sites require a time delay and secondary notification for password reset links, which you can’t reasonably do for login links.
Lifecycle management is an interesting point. There are some underlying assumptions that might not hold though—losing an email doesn’t necessarily mean downstream accounts should be auto disabled too. Think Facebook and college emails, for example.
> It’s not a higher level of security than password-based authentication. Why do you state that?
Personally I'm no fan of magic links.
But the people who do like magic links would say the typical 'forgot password' flow is to send a password reset magic link by e-mail. That means you've got all the security weaknesses of a magic link, and the added weaknesses of password reuse and weak passwords.
Of course you can certainly design a system where this isn't the case. Banks that send your password reset code by physical mail. Shopping websites where resetting your password deletes your stored credit card details. Things like that.
It's not about 'liking' magic links;
That means you've got all the security weaknesses of a magic link, and the added weaknesses of password reuse and weak passwords.
Is objectively true. I don't really 'like' magic links but I think they're a very easy to implement and simple to use for infrequently accessed systems. Arguably easier than user/pass and certainly more secure.
Even with those assumptions (which I question), it is only a higher level of security if you assume that your users are reusing passwords, or using low entropy passwords. Neither would apply if they are using a password manager, which a growing majority of web users are.
> It’s not a higher level of security than password-based authentication. Why do you state that?
It could be, depending on how the user has secured their email inbox access. I know I pay a lot more attention to my inbox than some random account. I don't have data, but I think this is true of most people.
I'm also more likely to enable MFA on my email account than I will on every random account I sign up for. And as far as the account providers, I trust the big email providers to be more secure than some random website with an unknown level of security.
You raise some valid points about tying access to a third party and what makes sense. It's not a simple issue.
That's a fair point, but does time delay or secondary notification (the latter could be done for magic links of course) really outweigh the practical security risk of password reuse, attacks, leaks etc? I would argue not, unless the user had a insecure email account for some reason.
Re Lifecycle management; Unless you're also linking a phone number or some other "factor" I think in a traditional user+pass scenario you're also SOL if you lose access to your $Email1 before you update your account to use $Email2, as changing your email to $Email2 would usually send a email to $Email1 to confirm the action. In that case you're in the same position as magic link login + email change functionality. Similarly Lifecycle management only comes for free if you don't implement email change functionality.
It's incredibly annoying to the user though
Oh, we support passwords! (And passkeys, and social login, and OIDC, and SAML.)
Just want to make sure magic links work as well as they can.
Different folks have different requirements, and since we're a devtool, we try to meet folks where they are at.
We actually recently added a feature which lets you examine the results of a login, including how the user authenticated, and deny access if they didn't use an approved method.
One weird reason I've personal run into: when building on the edge, like with cloudflare workers, you can run into timeout issues because of how long password hashing takes.
That should be only if you're on the free plan that has a 10ms time limit. Paid plan gets 30 whole seconds which is plenty of time to hash lots of passwords.
Because ≈everyone reuses passwords and so accounts get taken over.
A majority of internet users (>60% in 2024 and growing) use password managers and don’t reuse passwords.
In my experience 60% seems too high even for supposedly technical users (ref: I work in a dev firm), at least away from their jobs.
I definitely don't believe it for the wiser population (my gut, again based on people I know, says the number is more like 10%, maybe 15). Even the 36% figure on the report on security.org posted above seems dubious, I suspect they have some bias in their survey. Unless that is some people who use the iCloud password manager for some things and no password manager for everything else, so it isn't claiming 36% routinely use a password manager away from a few key accounts.
Do you have a source for that number? 60% seems extremely high based on non-technies I know.
Agreed. I'd be thrilled if it were true, though! Because password reuse (esp without MFA) is a big problem.
This is an extraordinary claim on two counts:
1. Sixty percent seems astronomically high, do you have a source?
and
2. Most "normal" non-tech-savvy people I know who do use a password manager (which I've typically installed for them), are revealed a while later to still use a variation of password reuse : either storing the same password per category of websites, or having a password template they use on all sites, e.g. "IdenticalSecretWord_SiteName"
I don't have the source, but don't think 1Password/LastPass/KeePass. Think the "would you like to save this login" built in to Chrome, Firefox, Edge, Windows, and iOS. These days, you have to opt-out of password management.
Right, use of a Password Manager does not imply they are using Password generation - it may just mean they click "Save this password" after logging in using a re-used password.
I'm surprised. >60% seems high even for tech literate software engineers!
- [deleted]
So what?
1) It means your users will complain that their account was hacked (even if it was their fault) and might cancel their service
2) hackers can exploit your system which hurts you (you are a VPS provider and someone mines crypto and you have to wave it for PR) or you run an email service and someone uses your app to spam (which hurts your email rep) etc.
one times codes are very vulnerable to phishing. users are prone to entering codes on any resembling website
I was gonna argue that you can fix this but I realized that you’re right. It’s a MITM attack where there’s really no way to stop it, same as passwords. It’s basically the same feature (sign in in a different browser) that also lets attackers in.
That said, here’s how I would mitigate it:
- Like usual, time based limits on the code - Code is valid only for the initiating session, requiring the attacker to create a paper trail to phish
If you do have a magic link & want to use code as backup for authenticating a different device/browser, you could:
- Compare IP and/or session cookie between the initiating and confirming window. On match, offer login button. On mismatch, show the code and a warning stating how it’s different, eg ”You are signing in a different device or browser, initiated from $os $browser in $city, $country, $ip - $t minutes ago.”
It’s not perfect though and may still be prone to phishing.
I've had success with sending a code, and the link takes you to a page where the input is pre-filled with the code, and you just have to click "Login".
Yup, that's a good option. Any kind of user action like a form submission is less likely to run afoul of a link checker.
> I think that a link to a page where you enter a one time code gets around a lot of these issues.
I've done both in my SaaS product - link is GET with the OTP in the link, the target page checks if the link is in the URL, and if not, then the user can type it in.
Only for signup, though. For sign-in, the default is to always have the user type it in.
- [deleted]
These days there's also to consider that some Mail Threat Protection Tools (at least Microsoft Defender in Exchange Online does this) click links in Mails to check them.
Recently ran into this issue as new mail accounts got confirmed automatically and magic links were invalid when the user clicked them, because Microsoft already logged in with it during checking.
Come to think of it, magic links by definition violate the principle that GET requests should not change state. Defender & preview tools are actually following the established norms here - norms that were established decades ago precisely because we hit the more broad problem with C, U & D parts of CRUD, and collectively agreed that doing destructive operations on GET requests is stupid.
You can GET a <form> which POSTs when you click the "log in" button.
Yes, but the GET itself isn't changing any state. The state changes only after clicking on the button. This is OP's point.
TeMPOraL said, "magic links by definition violate the principle that GET requests should not change state". That is a reasonable thing to think, but it is not true, because you can GET a <form> which POSTs when you click the "log in" button, unless you think a link to such a <form> page should be excluded from the definition of "magic link".
> unless you think a link to such a <form> page should be excluded from the definition of "magic link".
Yes. Linking to a form requiring user to press a button to submit an actual POST request is one proper way of doing it, and won't confuse prefetchers, previewers and security scanners - but it lacks the specific "magic" in question, which is that clicking on a link alone is enough to log you in.
Can't really have both - the "magic" is really just violating the "GET doesn't mutate" rule, rebranding the mistake we already corrected 20+ years ago.
(EDIT: Also the whole framing of "magic links" vs. passkeys reads to me like telling people that committing sins is the wrong way of getting to hell, because you can just ask the devil directly instead.)
Aha, then we agree on the facts, just disagree about nomenclature.
Your theological analogy is hilarious!
In your example, it seems to me that the POST request is the action that changes the state.
Agreed.
This is the way.
That seems like a really thoughtless idea.
What can you do to prevent automatic confirmation in that case?
I run an authorization service that allows to log-in using magic links and we managed to solve this. First approach was for the link opening GET request to do not log the user in, but to include an HTML page with JavaScript that issued a POST request with a code from the link to log the user in. This worked well for a long time, because email scanners were fetching links from emails with GET requests but did not execute JavaScript on the fetched pages. Unfortunately, some time ago Microsoft tools indeed started to render the fetched pages and execute JavaScript on them which broke the links. What works now is to check if the link is open in the same browser that requested the link (you can use a cookie to do it) and only automatically login the user in these cases. If a link is open in a different browser, show an additional button ('Login as <email address>') that the user needs to click to finish the login action. MS tools render the login page but do not click buttons on it.
The issue that MS tools introduced is broader, because it affects also email confirmation flows during signups. This is less visible, because usually the scanners will confirm emails that the user would like to confirm anyway. But without additional protection steps, the users can be signed up for services that they didn't request and MS tools will automatically confirm such signups.
> check if the link is open in the same browser that requested the link (you can use a cookie to do it) and only automatically login the user in these cases. If a link is open in a different browser, show an additional button ('Login as <email address>') that the user needs to click to finish the login action.
Thanks for checking if it's the same browser. Some companies don't care about that (cough booking cough) so harmful actors just spam users with login attempts in hope a user will click by accident. And puff, random guy gets full access to your account. I got those every day, if I ever needed to login this way I would not be able to figure out which request is mine.
Wouldn't that just log you in on the browser doing the clicking, instead of the attackers browser?
You mean in the booking example? They logged in the browser that... requested access. So basically anyone that knew your login/email.
I think it should check if browser requesting is the same as the one confirming, or just drop that whole dumb mechanism entirely.
Ok, what if an email has "click this link if it was you who tried to log-in", or "if it wasn't you"?
Will Microsoft automatically authenticate malicious actors, or block yourself from services built with assumptions that the email client won't auto-click everything?
Login links from my service were automatically clicked and rendered and I know that other services discovered similar problems. Based on this I think that it is very likely the case with all the links in emails, but I don't know if there is any additional heuristic involved that would treat some links differently.
See also this issue which suggests that all links are opened: https://techcommunity.microsoft.com/discussions/microsoftdef...
Note that this doesn't affect all Outlook users, this Microsoft Defender for Office 365 is a separate product that only some companies use.
That check for the same browser is a great idea. Thanks!
> But without additional protection steps, the users can be signed up for services that they didn't request and MS tools will automatically confirm such signups.
Indeed it's a bad thing but how bad?
The admins of some web service get a database of emails, send them those registration links, make their mail software create the accounts and? They end up with a service with accounts that they could create without sending those emails, before they send some emails to solicit users to perform some action on their (long forgotten?) account. There is no additional threat unless I'm missing something.
The admins have only an extra thin layer of protection because of the confirmation step but I think that any court can see through it.
The exploitation and potential damage would be service specific. Say a Dropbox like service for computer file syncing: An attacker creates an account for 'alice@example.org' and gets the signup email automatically confirmed. The attacker uploads some malware files to the account. After some time Alice attempts to create a valid account and resets password for 'alice@example.com'. Then Alice installs a desktop file syncing client provided by the service and malware files from the attacker get downloaded to her machine.
Another example would be if a company hosted a web app for employees that allowed signups only from @company.com addresses. In such case an attacker could be able to signup with such an address.
You are right. I didn't think about 3rd parties creating accounts on a service they don't control.
It defeats the email verification entirely. If that weren't necessary for something, why would the site require it?
The link leads to a page where you need to press a button (HTTP POST).
As far as I know there’s nothing.
The alternative is to send an OTP in the mail and tell the user to enter that.
In that way there is no link to auto confirm.
However, if you do that ensure that you have a way to jump straight to the page to enter the OTP because (looking at you Samsung) the account registration process can expire or the app is closed (not active long enough) and your user is stuck
> These days there's also to consider that some Mail Threat Protection Tools (at least Microsoft Defender in Exchange Online does this) click links in Mails to check them.
What an insane policy, why am I surprised Microsoft came up with it…
It's not actually insane if the application hosting the link follows the principle that GET requests should not mutate state.
This problem is ~20 years old from when CMS platforms had GET links in the UI to delete records and "browsing accelerator" browser extensions came along that pre-fetched links on pages, and therefore deleted resources in the background.
At the time the easiest workaround was to use Javascript to handle the link click and dynamically build a form to make a POST request instead (and update your endpoint to only act on POST requests), before the fetch API came along.
It is insane because it brings literally nothing security-wise (an attacker can easily detect that the link is being opened from something else than an end-user's browser, and not deliver the payload) while actualy compromising the security of their users (by allowing an attacker to know which addresses exist and which do not, which is very useful if you want to attack companies).
I've had this problem as a user, accidentally previewing a link in iOS by tapping for too long.
This is even worse for copying the link. On iOS the contextual menu comes with the preview, which will destroy the magic link.
4. Make sure the sign-in link on mobile works with your mobile app.
When McDonald's switched from email/password to magic links I had a hard time getting the magic link to work with the McD app. It usually would just open in the McD website.
Thus was quite annoying because about 98% of the time I eat McD's I would not do so if I could not order via the app [1].
I finally gave up and switched to using "Sign in With Apple" (SIWA). There was no way that I could find to add SIWN to an existing McD account, so had to use the SIWA that hides the real email from McD. That created a new McD account so I lost the reward points that were on the old account, but at least I could again use the McD app.
[1] They have a weekly "Free Medium Fries on Friday" deal in the app available for use on orders of at least $1. Almost every Friday for lunch I make a sandwich at home and then get cookies and the free fries to go with it from McD.
McD app is the absolute worst.
1) rooted or bootloader-unlocked Android devices are not allowed (granted it's easy enough to get past it for now but the checks are still there). 2) 2FA requirements as if anyone would bother to steal coupons from others
It appears that they want ordering burgers to have the same level of enhanced security as banking apps. Not even crypto or trading apps bother to block unlocked devices in such a way. Blocking rooted devices doesn't even make banking apps more secure but for them I can at least understand the reasoning.
I have heard that you are basically paying double what you normally would if you aren’t hunting for deals in mcd’s app these days. How much truth is there to that?
A lot. MCD corporate seems determined to get on the user data gravy train, and appears to be subsidizing it for the franchisees.
Three large fries ordered at the counter costs over ten dollars.
It’s not about data, it’s customer segmentation. Frequent customers are more price sensitive, and are willing to use the app to get all the discounts, while occasional customers will not, so they can capture both the more price sensitive part of the market while getting higher margins from occasional buyers.
As someone who spent many years segmenting customers and generating personalized marketing offers -- McDonald's is awful at this. I was a 2-3x/monthly customer (USA based) for years (even more frequent a decade ago, but I'm talking about since the app), ordering the exact same core items every time (except during breakfast).
When they began "value meals" last summer (which don't include their flagship items) they also removed the best deals from the app, the ones that did include Big Mac, QPC, 10-nuggets. I've placed one non-breakfast order in 6-8 months, whenever they started this.
I'm just one person, but if a customer declines from an expected 15-20 visits over a half-year period to 1, and you don't adjust your offer algorithm (and you're the biggest restaurant company in the world so no lack of resources), something is seriously wrong.
Whenever this happens to me I keep wondering how much I am of the A/B data test where I'm in the "less important group". Is it possible that their changes engaged (or profited from) the more active (daily/weekly customers) by making your situation worse?
Perhaps. Let's assume that the value meals is a massive hit and they are collecting far more revenue from customers who like it, than they are losing from people like me.
That's the whole point of data analytics and personalized marketing - even if the value meal works for most people they can still go back to sending me the offers and promotions I responded to previously, in an attempt to reverse my recent decline in spend/visitation. The app makes it possible to send individualized offers. There shouldn't be an entire "B" group where they just say, oh well.
They used to have great deals on the app in Germany. I used to go to McDonald's all the time. The deals suck now, and now I only go if I'm really craving a McMuffin Bacon & Egg.
Whatever they're doing also isn't working for me.
> they also removed the best deals from the app
They've captured the user base with the money that corporate was pumping into the app deals, and are in the process of enshittifying it by transferring the value to themselves instead of the users.
This can work in a lot of industries - I am skeptical fast food is one of them. Switching costs are low, alternates are plentiful, and collecting information (reviewing deals/prices across companies) is relatively easy.
If McDonald's enshittifies its deals while continuing to raise prices, it's way too easy for loyal customers to go elsewhere. I'm saying this as a huge fan and extremely loyal customer of McDonald's for decades... they are at serious risk of losing people like me. As I stated, I've gone from 15-20 visits to 1 since last June/July, whenever they made the big change.
We've got similar opinions here. I'm just pointing out that the overall experience here feels familiar, and it wasn't until reading this thread that I really put it together.
I agree with you that I'd be surprised if Enshittification works as well here as it does in tech, but maybe since there's an app involved, they just think they can get away with it. Who knows.
Sure they want user data to observe people's purchasing habits. But they already have that if you always use the same debit or credit cards like most people do.
But the more people use the app, the less cashiers they need and the less ordering kiosks they have to install. Plus customer satisfaction goes up because you can order ahead and your food is ready when you arrive. And getting used to the discounts means you probably won't switch to Burger King or Wendy's.
I think additional user data is a relatively minor part of it.
> you can order ahead and your food is ready when you arrive
That just sounds like a great way to get cold McDonald's...
> I think additional user data is a relatively minor part of it.
You're probably right about that, but I've always undervalued user data because I don't think it's ethical to exploit people like that.
I'm sure that a well-timed push notification suggesting a personalized meal deal right around hungry-o'clock is the real goal of pushing this stupid app on their customers.
>> you can order ahead and your food is ready when you arrive
> That just sounds like a great way to get cold McDonald's...
The idea is to order 3 or 4 minutes in advance, not half an hour before...
> your food is ready when you arrive.
The food does NOT start cooking when you order it if you’re picking up at drive thru. It starts cooking when you pull up to drive thru and give the magic code.
In fact if the food is not easy to prepare you get put in a special parking space, where you wait for your order to be prepared. If it includes soft drinks they might serve those before they make you go park.
Disagree on not going to BK/Wendy's. The "deals" game becomes a habit, switching costs are basically zero, people start to comparison shop each app for the best deal (like shopping for air travel). It's a bit of work because there is no single consolidator but it only takes a few seconds to scan each apps offers.
At this point, being a fast food chain that doesnt have an app with deals is probably not viable - but I am very skeptical it generates any loyalty.
I treat food delivery apps the same way. There’s no stickiness for me, I just check all of them and pick the one with the best coupons for my restaurant. A sign that this kind of stuff is very much a commodity. I usually end up on DoorDash, but that’s mainly because the current credit card I use affords discounts for it and as a result wins in the bidding war for my business
> But they already have that if you always use the same debit or credit cards like most people do.
Don't they have only the last 4 digits and the issuer of the card? It is likely enough but there will be some noise.
Not to mention any potential legal trouble if they used the card details without explicit consent. App contracts will get around that.
They have your name too. From what I understand, the tracking is generally done via something like the hash of the card number though. I've never heard of any legal or compliance issues with that, since the card number itself is not stored.
Submitted a Subject Access Request to McDonald's here in the UK. I'll update here on progress.
> Three large fries ordered at the counter costs over ten dollars.
This is kind of hilarious and depressing but I live in a high enough cost of living city in the states and I order mcd’s rarely enough that I cannot tell contextually whether your statement indicates this is overpriced or underpriced.
It depends on how recently they came out of the fryer, how fresh the oil is, and the grease-to-salt ratio.
I will sadly admit that the high price of fries only angers me when they're not fresh.
> Three large fries ordered at the counter costs over ten dollars.
Ask for a “bundle box” next time you’re there. They’re usually named after a local sports team.
Two Big Macs, two cheeseburgers, two fries, and a 10-piece nuggets for $12-15 depending on the market.
I think retail for just the Big Macs is that much these days.
No app required.
That is an incredible amount of cooked calories for that price. No idea this was a thing. I do remember being in college and local mcd’s doing the typical “if team wins chicken nuggets are $5 for 20” but never heard of this sports box concept
Much more - most McD's in USA charge over $4 for a large french fries.
It depends on order size. I think orders for one or two people over time you'd save close to 50% between deals and using points. For larger orders 20% off once a day is about the best you can do. (I'm my area/experience.)
"Normally would" is more likely, prices from the mid-2010's. The order I used to pay about $12 and change for in 2015 (I know this because I ate there at least once a week), is now about $13, by using the app deals.
However since the rollout of "value meals" last summer, they took away some of the better deals and now McDonald's is simply expensive (for McDonald's) even with the app.
The difference isn’t nearly that dramatic, but there are definitely savings to be had via the app.
One thing I recently found annoying with Slack was that I wanted the company chat on my phone, but I didnt want the company’s email on my phone given the overly broad control of my phone
so I got the magic link on their computer and then I made a qr code
but wait, the email quarantine system had altered the whole link so I had to extract that
but wait the redirect url back to slack was malformed because of the url encoding and i had to fix that and then make the qr code
like wow just give me a qr code or code instead in the original magic link email!
Would it have worked to forward the mail from your work email system to your personal email?
If it’s a big corp, they probably have strict data exfiltration policies for corp email.
Maybe this one email would have been fine, but if it gets tripped, it’s not worth the headache.
These same corps have opinions on where users can be logged into Slack as well. And ffiw most enterprises that have this kind of device management don't allow login via magic links via email anyways.
Yes, accurate, I was able to access some slack workspaces but not the main one without putting the invasive management profile on my phone
It wouldnt have worked any differently from the first qr code with quarantine, and been a flagged violation, eventually
Now your private email contents are subject to discovery.
Assuming we are talking about discovery in a civil lawsuit involving your employer the party opposing your employer can ask for all documents you have that are relevant to the lawsuit. It is then up to you to turn over those documents.
If they specifically ask for documents that are not relevant or if their request is too broad so will produce a lot of irrelevant documents your company's lawyers will tell them no.
By the time someone is actually specifically giving you a list of things to turn over that includes your private email it will only be asking for things that are relevant. Most of your personal email will be excluded.
Genuinely: why? All that is related to the business email is already accessible, it's just been forwarded elsewhere. The info is already known. What's to discover?
To discover where else you then subsequently forwarded it.
I'm not suggesting this is actually a problem, but that's how an argument could go.
It indicates that you used your this other email for work purposes. The point is that they don't know what's in there, and they want to see if you discussed stuff relevant to the case. The judge will deny such a request as a fishing expedition if there is no basis for believing that you used your personal email for work purposes. But if it is discovered that you started sending work emails to that address...
One of the biggest advantages of magic links is that they're unphishable while still being easy to use (unlike passkeys).
Having a code completely negates that advantage, as attackers can just set up a fake website that asks for the code.
Magic links should log you in on the device you click them, not on the device that requested the login session. Anything else, while being a little bit less annoying, is a security issue and should be treated as such.
That would require I have my email on every device I might want to log in with.
I don't like that for a number of reasons.
The conventional password system requires you to have a shared password manager on every device or that your reuse or memorize passwords. And that none of the service's users reuse passwords.
It's all trade offs, else it would be easy.
I can access my password manager on my trusted device, and manually type in my password for whatever service on any other device. This is exactly what I do for the rare but important time when I need to login on a device I don't want to have total access to everything.
I see. Yeah, I pitch a scheme in a direct response to them where you can still let a magic link authenticate a session on another browser/device.
Not to mention passkeys, which people seem to be so enamored with.
When using magic links, you can still support the common UX polish of letting a user log in on a different browser/device.
If the user opens the magic link in the same browser that initiated the email, then just log them in. Otherwise, present them with the Apple-style "Do you want to authorize a login from 1.2.3.4 using Firefox on iOS possibly located in Portland, Maine? [Authorize] or [Reject]".
1 and 3 are mentioned in the article. It’s still annoying if there is no password option.
> For example, an iOS user might prefer Firefox mobile, but their email client may force the link to open in an in-app browser based on Safari.
Hey, wasn’t Firefox on iOS based on Safari related tech anyways?
https://en.m.wikipedia.org/wiki/Firefox
> However, as with all other iOS web browsers, the iOS version uses the WebKit layout engine instead of Gecko due to platform requirements.
I do agree with what you’re saying though! Just those two in particular will probably have pretty good compatibility, which I was amused to find out when I looked into it.
> Make sure the sign-in link can handle email clients that open links automatically to generate preview screenshots.
Any suggestions on what needs to be handled here? My first thought is UA checking to see if it looks like a real browser.
The link is a "safe" GET request. The page loaded via the link should do an "unsafe" POST for the login, via javascript with a form button for fallback.
https://www.rfc-editor.org/rfc/rfc7231#section-4.2.1
>The purpose of distinguishing between safe and unsafe methods is to allow automated retrieval processes (spiders) and cache performance optimization (pre-fetching) to work without fear of causing harm. In addition, it allows a user agent to apply appropriate constraints on the automated use of unsafe methods when processing potentially untrusted content.
Exactly the same for email unsubscribe links, or a one click "buy now" link.
If you want to do this without JS just add a page with a "Click here to complete login" button that does the POST.
Automatic link pre-fetchers know JavaScript too and will trigger your JavaScript to post.
I've had to implement a system where if the link was minted x minutes ago, the JavaScript on the landing page is disabled.
It's just another arms race. It shouldn't be this hard, but in email it seems everything is additionally harder to do.
Why not just have a username & password. Why make everything so complicated? We just successfully got password managers deployed to most users, only to drop passwords entirely for a subpar system?
One example is an unsubscribe link. Legally, it would be no bueno to have it behind any sort of login.
Another is just counting if a link from an email was clicked. I want friction to be as little as possible. That's done by having some sort of redirect, but you have to use a JavaScript initiated post to weed add false positives. That's already ridiculous, but because of automated link prefetchers, you still need to disable that and show a f'n button.
And then I have to answer to clients that want to know why their clickthrough stats are down precipitously and I don't honestly have the wherewithall to explain the inner workers of every filter that snoops their email before they read it.
> We just successfully got password managers deployed to most users
Source?
Every desktop and mobile OS has a built-in password manager perfectly adequate for this use case, with encrypted sync and backup capabilities.
In my app, I just added an “Almost there!” Page with a button that the user needs to click. I still need to add a fallback option that uses a one time code for the other reasons mentioned above.
Save a browser cookie when the login is initiated. When the link is clicked check if the same cookie is present. If not, ignore it. Expire the link and the cookie after n minutes.
Surely this breaks the "email is not on same device as login" use case? At least with normal magic links, they're merely incredibly annoying but doable (via e.g. typing in the URL)
- [deleted]
That use case still works. In fact it works better because if you click the link on your phone you don't automatically get logged in on your phone browser (or your email client's in-app browser). You can then copy the same link on your desktop and it will work as expected.
I'm confused. How do you get the cookie from the original device to the other device?
It's the other way around. You copy the URL to the device that has the cookie.
How do you copy the link between devices? QR code?
As long as you also have a code to enter, then things will feel fine across devices.
After reading the other replies, this seems like one of the more effective approaches. Thanks!
Using a time-based expiration rather than a usage-based expiration should help
E.g. require to click a button to actually sign in, don't consume the token and establish the session on mere URL access.
Is 3 even possible?
[dead]
3 isn't really possible, because the redirect needs to take you back to the browser session where you initiated the login from.
It definitely does not.
Have your logging-in session wait for / poll "has visited magic link", and authenticate that session when it's done.
Tons of systems do this. It works great, and it can quite easily work without any web browser at all on the logging-in side because it just needs to curl something -> poll for completion and save the cookies -> curl against the API. A number of oauth flows for e.g. TVs work this way, for instance, because it's a heck of a lot easier than integrating a full browser in the [embedded thing]. Many app-based 2FA (e.g. Duo) works this way too.
So I misclick a link in my email client and the evil guy who requested in is now logged in on his browser god knows where? Surely that can’t be real. It sounds awful. TVs involve copying a code to make sure the right device is being authenticated, or the ones I’ve used have at least.
Duo 2FA works the same way. In principle yes. And it's basically always accompanied by a "click this link" -> "are you trying to log in, and is this you? yes/no" page to resist that.
Small code copying is also a very good answer though, yes. Roughly as easily manipulated, but nothing's perfect, and it's less "I didn't mean to click that button"-prone.
Yeah but I routinely click links in emails whereas logging in is the sole purpose of Duo. I could easily just intend to scroll the page and end up tapping the link.
so have that open a site that says "confirm login? y/n".
I don't mean to imply that just visiting the link should be enough to complete a login. That's a GET and there's a LOT of issues with doing anything important on GET. Just "do something on a different machine, then automatically complete login on the one logging in", and magic links to trigger that flow are a rather straightforward option.
There's no reason at all that it has to all occur on the same machine, and many reasons why attempting to require that doesn't work out in practice even when it does happen on the same machine.
Ah I see. Yes, that makes sense.
This seems dangerous:
1. Attacker starts a log in and triggers a magic link email 2. Email received and my browser client previews the link without my desire 3. Attacker is now logged in
That’s why you combine it with a check for source IP and tell your user that they need to approve from a device that has same IP as the one they are logging in on. So if I’m logging in on my laptop, and approving with my phone, it will be rejected if my phone is using mobile data while my laptop is using landline, but will approve if my phone is connected to WiFi of the same network my laptop is connected to, or if my laptop is tethered via my phone, because then I have same external source IP on both devices.
This scenario is a solution only in simplest cases. It doesn't work when someone routinely uses a VPN on the phone (when often uses free public wi-fi in airports, railway stations, markets etc) because of possible MITM attacks.
also some ISPs will give you a different IP every request
This has security and usability issues. NAT/CGNAT means a potentially large number of people can hijack your login.
The links are one-time use so you need to take this into account anyway or users simply can't login. It's usually done with a required button click after following the magic link. Or you can try JavaScript techniques to detect a real browser.
No "tons" of systems do not do this. If you come across one that does it was built by a team that has no idea about security.
TVs etc. are special cases because obviously there is no way to redirect to them, and even there developers will always have some kind of secondary checks like having you enter a code displayed on the screen.
When I sign on to a bank it sends an SMS. Then my phone prompts me to share that code with the brower, on my desktop. It's a neat QOL "feature" - but kinda feels too automated to be secure.
That's because the server recognizes both clients, and you are prompted to approve the other client from the client that has the code. You are giving permission to the remote client, not taking permission from the remote client.
The server recognized my device from the messenger/SMS app? That seems not correct.
But somehow, the desktop browser and my mobile are tied together for this app. But no other sites have this magic.
If you have an iPhone and a mac, most sites that use SMS OTPs work this way
Linux desktop, android phone.
I've come across dozens.
Google does it. Paypal does it. Duo does it. Lots of single-sign-on systems do it. All of those including not-TV scenarios, just normal computer-and-phone stuff, as well as sometimes other weird flows. Many of these are far beyond what most would label as "security competent", into "login security is a large part of their business and they have significant numbers of specialists hired".
(it is probably safe to say none are "truly secure" or "actually security obsessed", but I doubt that's actually possible in large quantities. the requirements are too steep, for both implementers and users.)
It's not the most common, certainly, nor anywhere close. But it's very far from nonexistent.
Where does Google do this?
Log in on browser -> push notification "is this you?" on your phone -> browser automatically continues when you say "yes".
But that's only as a second factor right?
Is that materially different? It's a login that's completed on a different machine, and automatically resumes on the intended one.
I might receive a magic link on my phone but then sometimes I'll copy/paste that over to my desktop or another device.
This works on 99% of magic links I've tried except for cases when they are trying to prevent account sharing. I remember the Bird bike app did this, where they required the magic link to be clicked on the same device login was initiated on. I was using my friends account and he would just forward me the link until one day this stopped working.
It seems like “prevent account sharing” and magic links are somewhat at odds by design.
The idea being the user(s) would then have to share a email inbox to share logins, not just a password. It might not be the most inconvenient - this is partly how Netflix did their "Household" lockdown. You can request a travel code and this gets emailed to the primary email.
I feel the way Netflix did this broke the social contract of profile sharing on purpose - before, if you were a good tenant, you could freeload off another paid account without inconveniencing them at all. Memes and jokes formed of still being on an ex-partner's account or how people would rename themselves "Settings".
Getting an email and being harassed for the code by all those account sharers? Much more open and open for annoyingness.
More than a shared password?
Not necessarily, some services would have the magic link verify the session that triggered it regardless of browser or device.
I assume it generates a session on the post-login screen and authorize that session upon accessing link
That has the problem of opening up an attack where the attacker requests the sign-in link, the person receiving the link blindly clicks it, and the attacker now has access.
People blindly click links all the time. It would have a low success rate, but would be more than 0%.