PoC: OAuth Authorization Code Theft

secure.unico.io - postMessage Wildcard Vulnerability | HackerOne #3519772

Vulnerability: The file web_auth_handler.js on secure.unico.io sends OAuth callback URLs (containing authorization codes) via postMessage(location.href, "*") to ANY origin.

1. Automatic Vulnerability Demonstration

How this works:
1 Click the button below
2 A popup opens running the exact same code as production web_auth_handler.js
3 The popup sends postMessage(location.href, "*") to this page (the attacker)
4 This page captures the URL automatically — no console, no credentials needed
Ready. Click the red button above to start the demonstration.

2. Code Comparison: Production vs Simulation

The callback simulation uses the EXACT same vulnerable code from production. The only difference is the URL — in a real attack, it would contain a real ?code= authorization code.

Production Code

Source: secure.unico.io/.../web_auth_handler.js

window.onload = function() {
  if (window.opener && window.opener !== window) {
    (window.opener ?? window.parent)
      .postMessage(location.href, "*");
  }
};

Simulation Code (callback.html)

Identical logic, runs on popup

window.onload = function() {
  if (window.opener && window.opener !== window) {
    (window.opener ?? window.parent)
      .postMessage(location.href, "*");
  }
};

3. Live Attack Flow (requires victim authentication)

Real attack scenario:
1 Attacker hosts this page on a malicious domain
2 Victim clicks the button below and authenticates on secure.unico.io
3 After authentication, web_auth_handler.js runs and sends ?code=REAL_CODE to this page
4 Attacker steals the authorization code and takes over the account

4. Verify Vulnerable Code in Production

Run this command to download and verify the vulnerable code directly from production:

curl -s "https://secure.unico.io/assets/packages/unico_core/web/plugins/web_auth_handler.js"
Or open this URL directly in your browser:
https://secure.unico.io/assets/packages/unico_core/web/plugins/web_auth_handler.js

5. Recommended Fix

// Replace the wildcard "*" with an explicit trusted origin:
postMessage(location.href, "https://secure.unico.io");

// Or validate against a list of allowed origins:
const ALLOWED = ['https://secure.unico.io', 'https://app.unico.io'];
if (ALLOWED.includes(new URL(document.referrer).origin)) {
    window.opener.postMessage(location.href, new URL(document.referrer).origin);
}

HackerOne Report #3519772 | Researcher: rcarpi | For authorized security testing only.