deniz.in

Markets

Weather

Loading weather

· via dev.to (home feed)

OAuth SDK accepted forged postMessage logins via missing origin check and predictable IDs

A security review of a web3 project uncovered an OAuth SDK that accepted postMessage events without checking event.origin, pairing it with sequential request IDs an attacker could predict.

OAuth SDK accepted forged postMessage logins via missing origin check and predictable IDs

A missing origin check in an OAuth SDK

A security review of a web3 project turned up a flaw in the OAuth SDK behind its "Sign in with Google" flow, according to a write-up published on dev.to. The bug sat in the SDK's handling of postMessage events — the mechanism a popup authentication window uses to talk back to the main application page — and it meant the application processed incoming login messages without ever verifying where they came from.

The flow itself is common: a user clicks a sign-in button, a popup opens, Google authenticates the user, and the popup passes the result back to the parent window via postMessage. The browser will deliver messages between windows regardless of origin, so the security of the whole exchange depends on the receiving listener validating event.origin before trusting event.data. In this SDK that validation was simply absent. The listener grabbed the payload and forwarded it onward without checking whether the message came from the legitimate popup, a malicious page, or anywhere else.

Sequential IDs turned the flaw into an exploit

A missing origin check raises an obvious question: how much can an attacker actually do with it? The answer depended on how the SDK matched incoming messages to pending OAuth requests, and the author traced that correlation mechanism back to its source.

The SDK tags each login request with a payloadId and waits for a popup message referencing the same ID. Rather than generating those IDs from a cryptographic random source, the code used a module-level counter that increments by one on every call. Anyone who saw request number 7 go out knew the next request would be number 8.

That predictability completed the attack chain. As soon as the victim's OAuth popup opens and the SDK registers its message listener, a malicious page the victim has open in another tab can call window.opener.postMessage() with a payloadId it predicted simply by counting. With no origin check in the listener, the SDK processes the forged message as if it had arrived from the real Google popup, and the attacker needs to guess nothing else, the author explains.

A known pattern, inconsistently applied

One detail stands out in the write-up: the same company maintained another package in the same SDK family that validated origins correctly, comparing event.origin against the expected endpoint and returning early on a mismatch. The knowledge and the pattern existed in the organisation's own code — it just never made it into the OAuth extension. The author attributes the lapse to familiar forces in larger codebases, such as separate teams, timelines and review depth, and argues that inconsistent security effectively hands attackers a roadmap to the weakest link.

The issue was reported through responsible disclosure, and the author is withholding the SDK's name until the vendor has had time to patch and publish its own advisory, so the specific package and full exploit details are not yet public.

The fix is one line

The remedy mirrors the check the company had already shipped elsewhere: compare event.origin against the SDK's expected endpoint at the top of the message listener and return early if it does not match. One line separates vulnerable from fixed, the author notes.

Why it matters

The lesson generalises well beyond a single SDK. postMessage shows up everywhere — login popups, wallet connectors, analytics tools, chat widgets, embedded iframes — and missing origin validation is a recurring bug class rather than an exotic one. Every message listener should treat an event.origin check as mandatory, and correlating asynchronous operations calls for cryptographically random IDs, because predictable sequential identifiers enable cross-window attacks and not just enumeration. It is also worth noting how the bug was found: not by a scanner, but by opening the source, tracing the message flow and asking what the code assumed versus what the browser actually guarantees. For any app using postMessage, the write-up's practical advice is blunt — go check your listeners now.

  • #web-security
  • #oauth
  • #postmessage
  • #javascript
  • #vulnerability-disclosure

Related posts