It’s around 12AM during a chilly Washington winter in 2019 – I was in bed and just about to fall asleep when I was jolted awake by a short burst of some insanely loud music. “Was that a car outside?”, I thought, trying to make sense of what was going on. After poking my head outside the window and finding nothing, I turned to my TV and saw Spotify playing something. Tired, confused, and without my glasses, I turned it off without reading the screen.
After getting jump–scared worse than most horror movies could do, I attempted to go back to sleep. As I finally managed to relax…
I scrambled out of bed (with glasses this time), checked my TV and sure enough, it was the source of the noise. After turning everything off from the power strip, I checked my Spotify account and found the immediately suspicious playlist called “Rap Türkçe.”
Piecing things together, I figured my account must have been hacked, and that the hacker had added a playlist and tried to cast music to my TV.
Sifting through my email, I found one from Spotify written in a foreign language confirming that an email had been added to my account. The next day, I contacted Spotify and their customer support helped me get my account back. Interestingly, they recommended that I remove the connection that allowed me to sign in with my Facebook account. I thought that was odd but filed it in the back of my brain for later.
Fast forward to a couple of weeks ago, and some of my co-workers mentioned looking for ideas for this month’s blog post. Needless to say, this incident was my first thought. We decided to take a closer look at what happened from a technical perspective to see if there is anything a company can do to mitigate this type of incident.
We learned that this was part of a wide-scale breach of access tokens from Facebook that happened during late 2018, allowing attackers access to anything with a “Sign in with Facebook” option.
Facebook is just one of many social identity providers (IdPs). When you enable your users to sign up with any of these providers, you’re trusting them to keep things secure. Events like this prove that full trust in a 3rd party IdP has its own set of risks. The easy recommendation here is to only enable email-based sign-up, but this introduces more friction when users sign up for an account, which is what these 3rd party IdPs were designed to prevent in the first place. So, the next question is: can we have our cake and eat it too? To answer that, we first need to take a look at access tokens.
Background: What are access tokens and why are they such a big deal?
From https://tools.ietf.org/html/rfc6749 Section 1.2
The diagram above is a high-level sign-in flow from the OAuth 2.0 RFC. In my case, I would be the resource owner, Facebook the Authorization Server, and Spotify’s APIs being the resource server that the access tokens are required for. Notice how having an access token lets you skip the authorization process, so the attacker doesn’t have to prove who they are. But thankfully, they don’t know the user’s real password either.
Solution 1: Two-factor authentication
Since two–factor is something the authorization server would typically perform before issuing an access token, this doesn’t help if the attacker already has an access token. However, an app could prevent the real user’s lockout by requiring the attacker to sign in again or complete an additional authentication factor before modifying the username, password or other critical data.
Solution 2: Account modification emails
If #1 isn’t implemented or the attacker has the credentials, the real user would still be notified that their account was modified without their consent. This was the case in my situation and helped give me full confidence that someone had hijacked my account.
The email change message I received was a bit suspicious considering I am not living in Turkey
Solution 3: IP and geolocation detection
If you happen to play PC games and are also unfortunate enough to have hacking attempts on your account, you’d know that Steam sends emails if a login was attempted from a device with an unusual IP. This is possible with IP geolocation, which works by using a database of IP address to location mappings. There are many options to choose from, such as libraries, web APIs and large cloud services.
https://ipstack.com/ has a nice demo on their front page that will show your location. They have a free tier of 10k requests per month. There’s also an open-source project affiliated with them. Even though it’s been deprecated, this might still work if you want to host it yourself.
Microsoft also recently launched geo IP-blocking as part of a preview feature in B2C called Conditional Access. Any apps secured by a managed identity solution like B2C will not accept tokens directly from a 3rd party IDP like a social network.
Say an attacker gets the valid credentials from a 3rd party that’s configured as a provider in B2C. With conditional access, we can block them even with the valid 3rd party sign in by defining some policies.
Below, I’ve defined a simple custom rule that demonstrates this. From the main menu under “Security à Conditional Access (preview), I went to “Manage à Named locations” and made this location:
Leaving the “include unknown areas” box allows us to exclude anonymous IPs from sources like TOR. After defining the location, I used it to make the policy below.
The app selected points to https://jwt.ms/, which allows you to view the contents of a token. This configuration blocked a valid, signed-in Google user from authenticating when behind a VPN from another country. It also blocked the same valid user without a VPN using TOR.
You can check out my demo over here and the code for my custom policies on GitHub. You can implement this yourself by following the instructions for built-in flows or the technical profile reference if you’re using custom policies.
However, this can be spoofed using things that hide your IP address, like a VPN or a proxy. An attacker that does their homework could use a VPN located in the real user’s origin country. This may not always be worth a hacker’s time, as they’re typically playing a game of large numbers. Or what if the real user is travelling to another country? If we had a way to uniquely identify a user’s device, we could let them in from a different country, or block an attacker spoofing their IP address from another device.
Solution 4: Device Fingerprinting
According to the Electronic Frontier Foundation, collecting enough data points about a user can be used to uniquely identify their device in an entire population. Skeptical or curious? They have a demo that will show if your fingerprint is unique among all the ones they’ve seen.
Interestingly, there are cloud services that do both fingerprinting and IP geolocation. FingerprintJS Pro and Microsoft Dynamics Fraud Protection (DFP) are two options. Geared towards enterprise users processing payments, both services are fully featured and consequently not cheap. Here’s a quick comparison table
Microsoft DFP | FingerprintJS Pro | |
IP Geolocation | Yes | Yes |
Device Fingerprinting | Yes | Yes |
User access history | No | Yes |
E-commerce fraud protection | Yes | No |
Pricing & scalability | $1000/month for 100k user account protection queries | $100/month for 100k queries |
Once you have a user’s unique device ID, you could securely store that as one of their registered and approved devices. This helps with the problems of only using IP geolocation above, but you would have to factor in if the additional cost and complexity is worth the extra security.
Solution 5: Continuous Access Evaluation
All of the solutions above require us to implement a feature or a service. Wouldn’t it be nice if we didn’t have to do any extra work? Luckily, the OpenID foundation, Microsoft, and Google are working on a solution called Continuous Access Evaluation (CAE). The problem is that one compromised account creates a “weak link” that can be used to access other accounts that the user owns. The authorization server can react to those events and notify the client, which then invalidates its’ cached access token. They also recognize that many current solutions focus on authorization during sign-in and not much past that, which is another gap this is intended to fill.
Weak links, focus on authorization only, client–side fix…sound familiar? I hope that this becomes an industry standard that can protect users from experiencing my situation or something even worse.
Our goal here isn’t to scare you, but instead, to raise awareness about one more thing that can go wrong with identity management and how you might go about stopping it. Stay safe and no, I’m afraid can’t recommend you any good Turkish rap.
Matt Takemoto
Software Engineer