Oh-Auth — Abusing OAuth to take over millions of accounts
Hackers could take over millions of accounts on Grammarly, Vidio and Bukalapak. The issue was fixed but users at other websites could still be at risk.
OAuth (Open Authorization) is one of the fastest adopted technologies in the AppSec domain. From its first introduction in 2006, as an attempt to introduce a standard authorization protocol, it has become one of the most popular protocols for both user authorization and authentication, and it’s being used by almost every major web service and website today.
One of the reasons for its huge popularity is its ease of implementation. Any developer, at any level of expertise, can use OAuth to implement a social login for a web service. But that simplicity can be deceiving — behind the scenes, OAuth is quite complex. It comprises many moving parts, and lots of little features are responsible for making everything work.
But wait. What about security? A new and advanced protocol, providing a quick way to authorize users over the Internet, must be safe to use, right? Well, almost right…
You see, the OAuth protocol itself is indeed correctly designed and is secure by nature. However, to use it with a web service requires integrating it into that service’s existing platform, which is where the trouble starts…
This post is the third and last in the trilogy describing common OAuth implementation issues that put many companies at risk. We conducted this research to learn and share rich technical details that educate the broader industry on the nature of potential OAuth implementation errors, their potential impact on a business, and how to avoid the gaps to better protect data, use OAuth more securely, and ultimately improve the security of entire API ecosystems.
All the security gaps identified by Salt Labs rendered major online services susceptible to credentials leakage, allowing complete account takeover, which, in the wrong hands, could have led to identity theft, financial fraud, access to credit cards, and many other perils.
Our first and second blog posts in this series presented how we could have exploited several OAuth vulnerabilities in Booking.com (a company with $16 billion in annual revenue) and Expo (a framework used by hundreds of websites like Codecademy) to take over accounts. Almost every modern website today allows social sign-in (“log in with your Facebook or Gmail account”) — OAuth is commonly the technology enabling that capability. These posts clearly showed that while providing a great user experience, OAuth, when implemented poorly, may pose a critical security risk to any web service.
This post reveals yet a new and different attack method on the social sign-in mechanism and OAuth implementations. We will demonstrate this issue on the real-world and very popular websites of companies, including Grammarly, Vidio, and Bukalapak.
Note that all companies took swift actions to address and fully mitigate the issues we described in this post. Security vulnerabilities can happen on any website — it’s the response that matters.
The outcome of this research impacted hundreds of millions of users cross the various in-the-wild flaws we located, and we believe these findings are just the tip of the iceberg. Just these three sites are enough for us to prove our point, and we decided to not look for additional targets, but we expect that 1000s of other websites are vulnerable to the attack we detail in this post, putting billions of additional Internet users at risk every day.
It’s extremely important to make sure your OAuth implementation is secure. The fix is just one line of code away. We sincerely hope the information shared in our blog post series will help prevent major online breaches and help web service owners better protect their customers and users.
Background — what is OAuth
OAuth is a modern, open authorization standard designed to allow cross-application access delegation — for example, allowing an application to read data from a user’s Facebook profile. Combined with the proper extensions, OAuth can also be used for authentication — for example, to log into an application using Google credentials.
When OAuth is used to provide service authentication, any security breach in it can lead to identity theft, financial fraud, and access to various personal information including credit card numbers, private messages, health records, and more, depending on the specific service being attacked.
How does OAuth work for authentication?
Before we take our deep dive into this specific vulnerability, let’s review the basics on how OAuth works. (If you are familiar with OAuth, you can skip this background explanation and go directly to the “Access token verification” section to understand the vulnerabilities we found.)
Assume you are John, and you want to connect to Randomsite.com using your Facebook account. What happens when you click on “Login with Facebook”?
In steps 2–3
After John clicks on login with Facebook, randomsite.com opens a new window to the following address:
https://www.facebook.com/v3.0/dialog/oauth?redirect_uri=https://randomsite.com/OAuth&scope=email&client_id=1501&state=[random_value]&response_type=token.
In this address, the client_id tells Facebook that the App is randomsite.com.
If it’s the first time that John connects to randomsite.com, Facebook will ask John if he agrees to give randomsite.com permission to access his Facebook account (only to read his email address for authentication).
If it’s not the first time he’s connecting, this Facebook access will happen automatically.
Note the redirect_uri parameter — it tells Facebook where to send the token in Step 4–5.
In steps 4–5
Facebook prepares a secret token for randomsite.com and redirects the browser back to redirect_uri. The exact redirection:
https://randomsite.com/OAuth#token=[secret_token]]&state=[Random_Value]
In steps 6–7
randomsite.com reads the token from the URL and uses it to talk directly with Facebook using the following API:
https://graph.facebook.com/me?fields=id,name,email&access_token=[secret_token].
The response is john@gmail.com.
Optional Notes
The flow in the example is called “implicit grant type,” which is common in single-page applications and native desktop applications that don't have a back end.
OAuth also uses an “explicit grant type,” which is similar to “implicit grant type” but the server (randomsite.com) receives a code instead of a token and needs to make an additional request to Facebook to exchange it for a token. We’re using the implicit grant type example here because it is easier to understand and relevant to this post.
Google, Apple, and other well-known vendors follow similar flows (across both implicit and explicit grant type). Other methods take advantage of the PostMessage feature instead of a redirection. The vulnerability we discuss in this post is relevant to all methods.
Access token verification
As you saw in steps 6 and 7, when the server receives a token, it makes an API request to Facebook to receive the identity of the user. Is it secured?
Let’s read the documentation of Facebook:
In other words, the first thing you need to do as a developer, before making an API request to Facebook to receive the identity, is to verify the access token. Otherwise, your implementation is not secure.
Yes — it is the responsibility of the developer to verify the access token.
What can possibly go wrong?
I will demonstrate the result on a website that doesn’t verify the access token: Vidio.com.
Lack of token verification on Vidio
Vidio is an online video streaming platform with 100M monthly active users. It offers a diverse range of content, including movies, TV shows, live sports, and original productions. It serves as a popular destination for users to watch, upload, and share videos across various genres and interests. The platform provides both free and premium subscription-based content, enabling users to access a wide array of entertainment options.
It's OAuth flow is almost identical to the Randomsite example that anchors the “Background on OAuth” section.
Note that when an application or website registers itself in developers.facebook.com, Facebook assigns it a new unique random App ID. In this way, Facebook knows which app makes the request. In the case of Vidio, the App ID is 92356.
When Dan goes to Facebook in step 3, Facebook generates for Vidio.com an access token that represents his identity (moreisless3dan@gmail.com). The access token has both the information of Dan (his email address), and the information of Vidio (App ID 92356).
In the diagram above, instead of calling the token “secret123” I called it “token_of_Dan_for_Vidio.com(92356)” to emphasize the fact that Facebook knows that Vidio.com asked for an access token and generates an access token specifically for Vidio (App ID 92356).
As you read previously, according to the Facebook documentation, when Vidio.com receives the access token from the user, Vidio should verify that the access token was generated to its App ID (92356) by calling the https://graph.facebook.com/debug_token API.
Facebook doesn’t do the verification for them automatically. As noted, it’s the responsibility of the developer to verify the token.
The Vidio.com website, however, does not verify the token, so an attacker can use an access token generated for another App ID.
Let’s see how an attacker can exploit this gap to achieve a massive account takeover on thousands of accounts.
Creating a malicious website for collecting tokens — YourTimePlanner.com
Let’s imagine that the attacker built a malicious website and called it YourTimePlanner.com:
The attacker publishes YourTimePlanner.com as a legitimate website – for example, as a shopping site that offers significant discounts or an attractive app on an app store that helps you manage time. Most people don’t mind using sign-in via their social-media accounts to new websites because it shouldn’t have a security risk. When you sign in using your social media account, you share only your email address, which is not sensitive information. The worst thing that can happen, people assume, is you’ll get some extra ads sent to your email inbox.
Let’s assume thousands of people connect to YourTimePlanner.com:
The attacker has thousands of access tokens that represent real users and were generated for TimePlanner.com (App ID 328..).
Let’s take an example access token: token_of_Dan_for_TimePlanner:
"EAAut0eRcO1QBO9IrSS8xryMLF9wdSuGMGXiVbgJEsMjhLkqRhLYb0z1RcDJ9yw8RTvN0n5VTEfTazaifUYYVcovFutFG3GUP8feKftp4U7gXJaz0lY9wNttKZBqZAP8ZCszUHZAwN8o5iZBKLSyF7UZAUsITmcs57EXDW44bEGdZBt6rQRkoeGMgtPghfgHrqefbIfBkdyLneTqPMZD"
Using Facebook token debugger, you can see all the information about the access token:
This token represents Dan Bro (moreisless3dan@gmail.com) and was generated to TimePlanner (App ID 3287341734837076).
What will happen if the attacker inserts this token to the vulnerable website Vidio.com, which has a different App ID (92356)? If Dan has an account on Vidio.com tied to this email, that might enable account takeover. The attacker could publish YourTimePlanner.com on a place with a lot of Vidio.com users, generating lots of these credentials, and take over all their accounts.
The API reached by “/api/facebook/auth” in Vidio.com is responsible for receiving an access token from the user and returning Vidio.com credentials. The attacker sends to this API the access token “token_of_Dan_for_TimePlanner”:
It worked!!! Since Dan has an account on Vidio.com, the attacker sends an access token that represents Dan from YourTimePlanner.com into Vidio.com and completely takes over Dan’s account on Vidio.com.
This screen shows that the attacker is connected as Dan to the Vidio mobile app. To be clear on what happened: Dan (our victim) just connected to a “legitimate” website YourTimePlanner.com using Facebook,, and an attacker was able to take over his account on another website, Vidio.com, without any user interaction. The attacker has full control on that account.
And we just got started…
When we found this vulnerability, Vidio fixed it immediately and added Salt Security to its Hall of Fame:
https://www.vidio.com/pages/vidio-bug-bounty-program
I really appreciate companies that offer bug bounty programs or Hall of Fame lists like Vidio. It shows these companies take security very seriously. It's important to recognize that security vulnerabilities can arise in any type of website, including well-secured ones such as Vidio. It’s the response that matters, so thanks again to Vidio for taking this secure approach.
According to Vidio, the vulnerability pertained mainly to the Facebook OAuth implementation; it was active only during a certain period because of a migration from one Facebook OAuth App to another.
Lack of token verification on Bukalapak.com via Facebook login
Bukalapak is one of the largest and most prominent eCommerce platforms in Indonesia with 150 million users. It serves as a comprehensive marketplace for various products and services, connecting millions of buyers and sellers. The platform offers secure payments, logistical support, and buyer protection. With its significant presence in the Indonesian market, Bukalapak has contributed to the growth of online retail in the country.
Account takeover on eCommerce platform like Bukalapak poses a threat to the security of user's personal and financial data.
The login flow of bukalapak.com is very similar to vidio.com:
The endpoint “/fb_login” in accounts.bukalapak.com receives an access token as one of the parameters and returns the credentials of the user in Bukalapak.
Bukalapak doesn’t verify the access token, and therefore, by inserting a token from another website — “token_of_Dan_for_TimePlanner” (like before, we assume Dan has an active account on Bukalapak) — I could get the credentials of Dan in bukalapak.com and completely take over his account:
And also a technical image using Burp:
(In the image above, the attacker received the credentials of Dan in Bukalapak)
This screen shows that the attacker is connected as Dan to Bukalapak.com. Just to be clear — Dan (our victim) just connected to YourTimePlanner.com, and an attacker takes over his account on two popular websites — Vidio and Bukalapak.
We provided the details to Bukalapak and they quickly fixed the issue.
It's important to mention again that security vulnerabilities can arise in any type of website, including well-secured ones. It’s the response that matters, so thanks again to Bukalapak for the quick response and fix.
Bukalapak provided us this commentary:
“Nonetheless, Bukalapak has implemented OTP (One-Time Password) as an additional security layer to enhance user account security. This feature can be found on the user's profile page, under the security menu. We are committed to continuously improving our security measures to protect our users' sensitive information.“
Finding OAuth vulnerabilities on Grammarly — and gaining full account access
Grammarly.com is an AI-powered writing tool that helps users improve their writing by offering grammar, punctuation, and spelling checks as well as style suggestions and vocabulary enhancements.
They boast 30 million daily users. Users can use the Grammarly Extension/App or the company’s web editor directly which is available at Grammarly.com. Unlike the Extension/App which doesn’t store data, the web editor at Grammarly.com stores the data directly within Grammarly's account, which means an account takeover would give an attacker access to the victim’s stored documents. I myself am using Grammarly’s web editor for help as I've been writing this blog and writing emails, messages and documents in general.
Grammarly acted swiftly to address the issue and said that they fixed the issue before it could be exploited. We applaud Grammarly for the speed of its response and its prioritization of security.
Grammarly provided this commentary:
“We are thankful to Salt Security for their high-quality report and ethical collaboration. When we received notice from Salt Security, we moved quickly to address the vulnerability and launch an investigation that confirmed that no Grammarly user accounts were compromised by this issue. The safety of our customers’ data is at the center of our business, backed by Grammarly’s robust, comprehensive security infrastructure that we continue to strengthen and invest in. As part of our commitment to transparency and dedication to resolving issues before they can be exploited, we encourage and invite external security researchers to participate in our long-standing bug bounty program.”
The technical details:
Let’s see how OAuth works in Grammarly:
- The user clicks on “Sign in with Facebook” and the following URL is opened: https://www.facebook.com/v9.0/dialog/oauth?client_id=945246385586366&redirect_uri=https://www.grammarly.com%2Fsocial%2Fredirect&response_type=code&state=[random]&scope=email&auth_type= Note that the client_id/app_id is 945246385586366.
- Facebook redirects the user to Grammarly with a secret code: https://www.grammarly.com/social/redirect?code=[code]
- Grammarly sends this code to https://auth.grammarly.com using a post request.
- https://auth.grammarly.com authenticates the user based on that code and returns the user credentials at Grammarly.com. (In the back end, Grammarly should exchange the code for an access token.)
OAuth supports two response types — a token or a code. On the Vidio and Bukalapak sites, the response type is a token, and we could perform the token reuse attack. When the response type is a code, like in Grammarly, the server needs to exchange it for a token, and in this exchange, Facebook does an extra validation for the app ID. In other words, this kind of attack doesn’t work if the website uses code.
So that’s it? We can’t attack Grammarly? Actually yes, we can.
Look at the request to https://auth.grammarly.com. Notice the word “code” in the request. We wondered — would it accept other things?
Instead of code, I tried to insert “token” but it didn’t work.
And then I tried a brute force of other terms, including:
- Token
- facebookToken
- FBToken
- Ftoken
- AccessToken
- Access
- SToken
- Tk
- T
- Access-token
- Access_token
- and others...
The winner turned out to be access_token:
I changed “code” to “access_token,” inserted the token of Dan from Timeplanner, and got the credentials of Dan in Grammarly.com. And like with the other sites, the Grammarly implementation did not perform token verification. So, I achieved full account takeover.
With full control of Dan’s account, we can see all his private documents:
Summary
If you connect to YourTimePlanner.com (a “legit” website or app that you just found), an attacker can use the credentials harvested there to take over your accounts on dozens of websites, read your sensitive data, and perform actions including credit card transactions on your behalf. This holds true even if you don’t use Facebook to sign-in on those target websites. You only need Facebook to connect once to YourTimePlanner.com, and the rest can be done by the attacker without your interaction.
In this post we demonstrated the attack on Vidio, Bukalapak, and Grammarly.com. Because this vulnerability was so urgent and widespread, we decided to stop the research and publish the findings as quickly as possible, so other organizations can remediate this flaw. We are certain many other websites have this same vulnerability.
When was the last time you connected to a new website or application??!
Mitigating this serious vulnerability
All targets — Vidio, Bukalapak, and Grammarly — released a fix, and the issue no longer exists.
What can you do to prevent this vulnerability? Follow the instructions from Facebook and other sites that support social logins and VERIFY the tokens!\
No company can be completely secure. We've discovered vulnerabilities in big companies before, including banks and other institutions with highly valuable data. The fact that Grammarly, Vidio, and Bukalapak all responded so quickly to these security measures is what matters. Since I’m a daily user of Grammarly, and I care about security, I am very happy to see this dedication to security.
To learn more about how Salt can help defend your organization from API risks, you can connect with a rep or schedule a personalized demo.
Disclosure Timeline
We worked through the following timeline in this coordinated disclosure process. Again, we thank Vidio, Bukalapak.com, and Grammarly.com for taking action to resolve these critical vulnerabilities.
- Salt Labs discovers the vulnerability in Vidio.com: Feb 23, 2023
- Salt Labs discovers the vulnerability in Bukalapak.com: March 9, 2023
- Salt Labs discloses technical details to Vidio and Bukalapak security teams: March 9, 2023
- Vidio security team confirms security disclosure and adds us to its Hall of Fame: March 17, 2023
- Salt Labs discovers the vulnerability in Grammarly.com: April 3, 2023
- Salt Labs discloses technical details to Grammarly security team: April 11, 2023
- Bukalapak security team confirms security disclosure: April 17, 2023
- Vidio security team deploys a mitigation: June 15, 2023
- Bukalapak security team deploys a mitigation: June 16, 2023
- Salt Labs confirms exploits are no longer working and security gaps have been resolved in both Vidio and Bukalapak: June 19, 2023
- Grammarly security team deploys a mitigation: July 13, 2023
- Salt Labs sends Vidio, Bukalapak, and Grammarly security teams this technical blog detailing the vulnerability: August 22, 2023
- Salt marketing team shares draft of blog and press release with each company’s marketing team: October 16, 2023
- Salt publishes blog and press release: Tuesday, October 24, 2023
If you will be onsite at SecTor Aviad Carmel and Yaniv Balmas will be hosting a speaking session titled: "Uh-OAuth! - Breaking (and Fixing) OAuth Implementations" — Wednesday, October 25, 4–5 p.m., Meeting Room 718A.