← Back to Writeups
CVSS 8.1HIGH

OAuth Misconfiguration in EdTech App: From Low Privilege to Full Account Takeover

#OAuth#Session Misbinding#Federated Identity#Account Takeover#Privilege Escalation

Published: March 2025

🧠 TL;DR

A subtle OAuth misconfiguration turned a basic student account into a full instructor-level takeover vector. Through session misbinding, trust flaws in federated linking, and blind endpoint trust, I escalated privileges silently — without phishing, password resets, or brute force.

The exploit chain allowed enumeration of unlinked federated accounts and arbitrary account association — leading to complete privilege escalation.

🗺️ Target Application

The target was an EdTech cloud platform supporting both standard email/password accounts and federated campus logins via OAuth. Users could link their campus identity to the main platform account — and that’s where the issue lived.

  • Standard app users (email/password)
  • Federated OAuth users (campus logins)
  • Loose account-linking mechanism

🔓 Vulnerability Breakdown

Affected endpoints:

  • /federation/account/association/check
  • /student/federated/associate

These endpoints failed to enforce proper session validation, trusted origin headers, and lacked mutual consent verification. Together, they created a perfect storm for OAuth misbinding and silent privilege escalation.

🔢 Exploit Chain Walkthrough

✅ Step 1: Auth as a Basic User

I logged in as a normal student user, capturing my active session cookie for later use. The goal: abuse this valid session to bind it to another account.

Valid account not yet federated

My standard student account prior to federation linking.

🔍 Step 2: Account Enumeration

The endpoint /federation/account/association/check was accessible anonymously. By sending POST requests with identity parameters, I could determine which federated identities were already linked — and which were still “available”.

This effectively became an oracle for valid identity IDs.

Federation account association check

Checking account association status via open federation API.

🔄 Step 3: Link the Accounts

I crafted a POST request to /student/federated/associate:

{
  "victim_identity_id": "X",
  "attacker_account_id": "Y"
}

Headers:

Cookie: session=[student_session]

No verification occurred to confirm that I owned either the attacker or victim identity. The server simply linked them.

Federation link request result

Federation successfully linked without any ownership validation.

💥 Step 4: Full Takeover

Once associated, my student session gained access to the victim’s account — including instructor tools, class data, and personally identifiable information (PII).

After association account view

My session post-association: now operating under instructor-level privileges.

📦 Real-World Fallout

  • Instructor accounts hijacked silently
  • Full access to courses, grades, and user data
  • Privilege escalation from student to teacher
  • Potential for automation and mass exploitation

🛠 Techniques & Approach

  • Deep understanding of OAuth and session-binding logic
  • Manual probing of federation endpoints
  • Creative chaining of passive and active responses

🔒 Remediation Strategies

1️⃣ Session Binding

Link actions must verify active ownership of both the initiating and target accounts.

2️⃣ Rate Limiting

Protect association-check endpoints from enumeration via brute force or batching.

3️⃣ Explicit Consent

Require user confirmation before linking accounts or merging identities.

4️⃣ Notifications

Notify users of new or removed federation associations in real time.

🧠 Final Thoughts

OAuth depends on trust — but trust must always be verified. This bug didn’t break crypto or require social engineering. It simply exploited misplaced confidence in session state and linking assumptions.

In federated systems, assuming “identity equals ownership” is dangerous. One missing session check can mean total compromise.