LinkedIn 'One Time Login' Feature

Someone was worried by an email they received from LinkedIn, about a connection attempt from Moskva, Russia.
Let's dig into this to check if this is a security incident, or something else.

The email that someone forwarded me to check what's going on

Check email legitimacy

First, we have to ensure that this email comes from LinkedIn, and is not a forged phishing. This can be done by checking the email source code (open the email in Thunderbird, and click "other" on the top right, or "Autres" in French, then "show Source").

The source of the email (headers)
And its content, so we can check the links and such.

Check for SPF, DKIM and DMARC pass (any failure would indicate the email was not sent from LinkedIn servers). Also check for the enveloppe sender (not the "From" field in the header: this may contain anything the sender wanted). Last, check the content for grammar spellings, code structure, and links (domains).

Here, we can see that the headers (SPF, DKIM, DMARC…) are correct, the headers seems correct, and the links seems correct, so all look like this email comes from LinkedIn, and is not a phishing.

Is that a feature?

Now that we know it's a legit email, let's see where (what feature) generated it. A quick web search shows that the "One time Sign in" mentionned in the email is indeed a LinkedIn feature.

One-Time Sign in, meaning "password less"

Testing the "feature"

Let's try: go to LinkedIn Sign in page, and click the "Sign in with a one-time link"
The user email is asked
Once filled, an email should be sent
And indeed, I've received the email (in French)

The issue

It seems we found the feature that triggered the email, and that worried the user. And I do agree: when reading the email, we see "Didn't do this? be sure to change your password" but, no! This is false! We did not need the password when doing this test, we only used the email (which might be considered as "public knowledge", since LinkedIn had several past data breaches that revealed emails (scroll down to "LinkedIn" in that HaveIBeenPwned page to see the at-least 3 data leaks), and because lots of people do not keep their email adress confidential, which makes sense if you want recruiters, friends and such to find you).

This sentence makes no sense

Contrary to what LinkedIn says here, your password is not compromised.

Is it working?

What happen if we click that "one time link"? Let's see if we get logged in

We are logged in when clicking the link

And yes, we are. So the feature is working as intended.

Now that we know about the feature, and that it's working, we can ask ourselves: since the original user did not do this action and did not request a one time sign in link, who did that and why?

Why using this?

We confirmed that the feature is working, so now, let's try to find out why the Russian actor (from the user's email location) is using this feature.

Log into user's account

First simplest reason (and the most impactful one) is to try to log into the user's account. So we will study the security stength of that link (I won't study it from a cryptographic point of view, nor by tampering the ids/tokens: they are safe enough, I will only study it from other perspectives for now)

I first tried to reuse the same link that I already clicked. So I copied it, and pasted it in a private browsing window. I was wondering if the link was still usable even after having been clicked once (so the link could be used multiple times to log into LinkedIn within the 15 minutes window).

Clicking the same link again fails

And it fails. So, good thing, the link is not usable several times, which is good to avoid replay attacks.

An attack scenario could be that the link's requester has a way to see the one-time login link, and so, they generated it, got it (from your mailbox by accessing it, or by spying on the internet SMTP network since emails are not secured by default.

This could be countered by forcing the link to work only for the browser that requested it. So I've tried generating a new link, and I've opened it in another browser (Chromium)

Requesting a new link from one browser (Firefox)
Opening it in another (Chromium): it works

Since this test worked, it means the link can be opened in any browser, which is quite risky because it means anyone finding the one time access link can log into your LinkedIn account.

If you're a product manager and plan on implementing a similar feature for your product, then please restrict the link usage to the browser that requested it.

This contradicts the help page that clearly states to use the same browser
And same for the kind LinkedIn CM that replied to me on a tweet

Really, when I say "kind", I mean it: I wasn't expecting any reply from any LinkedIn support. So it was really nice to see them reply on this topic :)

…neither to the IP

Maybe it's tied to the IP adress, making it a bit more secure? Let's try.

My device has this IP
I request a new link from this device
Then I switch to another device, with an isolated VPN and another IP
And it works (I've also switched browsers btw)

So the link is not either tied to the IP: anyone, anywhere in the world can use the one time signin link, which is a very, very risky practice.

Persistence

What actually "scares" me most, is that from a logged in account in LinkedIn, you can achieve easy persistence. When logging out, just say "memorize and quit session".

Log out and say "memorize"
Now you are logged out
But if you log back in, you don't need a password
So this allows an attacker to persist easily
The only way to spot them is in the account's preferences
Then in the identity & securyt, you can see they stored the session on their device
You may also see they logged into your account
If you terminate their sessions
They will be logged off
But they can log back in with this "memorize" feature
So you must actually revoke the session stored on the device
Once revoked…
…then the logged-in sessions are also revoked (so no need to do both)…
…and then only they will need the password to log back in (which attacker does not know)

Brand image degradation

By doing some searches on the web (as you can see in the previous screeshots, in the tab bar showing several tabs opened to twitter and reddit), one may see that this feature is widely abused these last months. This generates a degradation in the user's perception of LinkedIn (both from a security and UX perspective).

This could be the goal of the attacker group (more like "feature abuser group"). This does not really represent any direct security threat, and is very hard to measure from a financial perspective (brand image loss is very tricky to quantify), but it might be a valid reason for abusing this feature.

The weird suggestions

On Reddit (and on the internet in general), you might see weird and kinda absurd suggestions about "why is some (attacker) group abusing this feature".

Insider

I clearly doubt all the insider ones (like "one has access to LinkedIn DB and uses this feature to access your account"), because it makes no sense on such scale. It could be a plausible explanation if some very-valuable accounts were targeted (like CEO and politics), but for regular random users, it's dumb. Some insider with such knowledge and accesses would have way more powerful means to be a threat.

Someone spies the SMTP servers

Another theory I crossed the path of was "someone spies on SMTP servers, so they can see the emails and can use the one-time link in there". Credible, and a reason why securing emails are important, yet still absurd. Because someone with such power would not need to use OTL, they would just use the "forgot password" feature, which sends you an OTP via email to change your password.
So, it's not a valid theory either.

A zero-day

This is the only theory that could make sense: some attacker group has found a zero-day in this feature, and is exploiting it. But it will be very hard to prove, and I actually doubt such vulnerability exists. So I'll personally consider this as "wrong theory" altho it makes sense to believe it's correct.

Crawlers

What makes more sense to me, seeing that the OTL comes sometimes from Russia, sometimes from US, sometimes from other countries, is that it comes from purely bad written bots. Bots are crawling all pages of all the web all the time, and they certainly find this page on a regular basis. When accessing the OTL page, LinkedIn requires to enter an email. And so, the bot fills it with a random email (from whatever database they use).

This theory means there is no "attacker", just badly written bots all around. So it can be considered as a "we are in La La Land" point of view. Which is a valid objection.

(Time-based) Oracle

But the most credible reason to me is that this feature is used as a Time-based oracle to check whether the email adresses exist in the LinkedIn database. Let's make a showcase.

First, we got back to the OTL feature, open the console (F12), and then enter a valid email to get a new login link.

We request a login link
We then go to the console, and check the server's response
We redo the same but using an email that is not in the LinkedIn database: same result

If the result had differed (eg: the server responded with "FAILED" instead of "PASS"), then we would have an "oracle" that allows us to check if an email is registered in LinkedIn. We would then pick a database of emails (leaked from LinkedIn or not) and abuse the OTL feature by requesting a link for each email. All those that would have "FAILED" are not registered in LinkedIn and all those that would have "PASS" are.

"Password lost" and similar features (like this OTL) are often very good oracles for user emails/nickname in web products.

But now, if we check how long it took for the server to respond to the incorrect email request…
…and compare it when using a valid email (registered in LinkedIn), we see a difference

Time-based oracle are often hard to exploit, but here, the different is exceptionnaly clear. So this is probably why this feature is so much abused recently IMO: to tell if an email is actually registered in LinkedIn or not

To confirm this theory, we should try to reproduce it, but I've requested too many OTL for my LinkedIn account, so OTL are currently all denied. Hence, I've tried with someone else's account (a friend's one). I don't know what email they use for their LinkedIn, but I know some of their email adress. So I've tried these email adress in the OTL feature, and poo, one took like 2 seconds to respond.

Trying OTL on my account again failed…
…with a BAD_REQUEST response
So I first retried with a dumb email that is not in use: 6 attempts in a row return "OK" message

This means that we also have a non-time based oracle: if we want to know whether an email is registered in LinkedIn, we can simply submit it 6 times in a row. If the server responds with all "OK", without reaching the max OTL number per day limit, then the email is not registered in LinkedIn. If we get an error response like above, then the email is certainly registered.

I'm not 100% sure if 6 calls in a row are required, but the idea is valid seeing these results.

These 6 attempts responded instantly (likely in 300ms)
Now I try one of the email adresses of my friend to see how long it takes for the server to respond
And suddenly, it took way longer! So my guess: this is the emails they use on their LinkedIn
And they confirmed they do use this one!

In the end, we do have a time-based oracle for checking if an email is registered in LinkedIn.
Also, we even have a non-time based oracle by requesting OTL multiple times for a single email, and check if we get an "error" response or not.
Last, we have found that the link is not tied to the browser it was requested with, contrary to what the help says.

Edit: The HackerOne report has been considered "Informative" and closed, so I published this article.