_handleOAuthMessage validates the event.origin against the proxy URL, but when the origin doesn't match it logs a warning and falls through anyway as long as _oauthPopup is truthy:
// scripts/patreon-auth.mjs:171-179
const expectedOrigin = new URL(this.proxyUrl).origin;
if (event.origin !== expectedOrigin) {
console.warn(`${MODULE_NAME} | OAuth message from unexpected origin: ${event.origin} (expected: ${expectedOrigin})`);
// Still process if it's from the popup we opened
if (!this._oauthPopup) {
return;
}
}
Existence of a popup reference does not prove the message came from that popup. Any page in any tab that knows our OAUTH_CALLBACK_MESSAGE_TYPE could postMessage a forged session token to the parent window during the OAuth flow, and the client would accept it.
Realistic exploit difficulty is moderate (the attacker would need to time the message window and know the message shape), but a Patreon session token is a sensitive credential and the comment shouldn't override a security check.
Suggested fix: hard-fail on origin mismatch — no fallthrough. If there's a legitimate case where the callback origin differs from the proxy origin (e.g. proxy on a different subdomain than the OAuth callback host), allowlist the specific origin explicitly instead of trusting "popup exists."
_handleOAuthMessagevalidates theevent.originagainst the proxy URL, but when the origin doesn't match it logs a warning and falls through anyway as long as_oauthPopupis truthy:Existence of a popup reference does not prove the message came from that popup. Any page in any tab that knows our
OAUTH_CALLBACK_MESSAGE_TYPEcouldpostMessagea forged session token to the parent window during the OAuth flow, and the client would accept it.Realistic exploit difficulty is moderate (the attacker would need to time the message window and know the message shape), but a Patreon session token is a sensitive credential and the comment shouldn't override a security check.
Suggested fix: hard-fail on origin mismatch — no fallthrough. If there's a legitimate case where the callback origin differs from the proxy origin (e.g. proxy on a different subdomain than the OAuth callback host), allowlist the specific origin explicitly instead of trusting "popup exists."