Skip to content

in-app wallet: AutoConnect consumes URL auth tokens with no provenance check (add an opt-out / nonce gate) #8861

Description

@gitchadd

Summary

<AutoConnect> consumes in-app-wallet auth material directly from the page URL on every load, with no check that the app initiated the flow. getUrlToken() reads authCookie / authResult / authFlow / walletId from the query string or the hash and hands them to the connection flow, which persists the cookie and signs the browser into whatever wallet the token names. There is no origin, nonce, state, or signature validation on this path.

Because the same params are what a redirect OAuth login legitimately returns, an integrator who mounts <AutoConnect> globally (the documented pattern) cannot distinguish a real redirect return from an attacker-supplied link. A link of the shape https://app.example/…?walletId=inApp&authCookie=… (or authFlow=link&authResult=…) therefore causes an unsolicited wallet connection: the visitor is silently connected to a wallet chosen by whoever crafted the link, or the link flow attaches an external profile onto the active account. The params are then scrubbed from the address bar via pushState, so nothing is visible to the user.

This is a request to add a built-in provenance control (or an opt-out) so integrators are not each forced to reimplement one.

Where (v5.119.4)

  • packages/thirdweb/src/wallets/in-app/web/lib/get-url-token.ts — reads the params from window.location.search and the hash; a grep for nonce|state|origin|verify|signature in this file returns only the pushState that scrubs them.
  • packages/thirdweb/src/wallets/connection/autoConnectCore.tsauthFlow === "link"handleLinkingFlow; authCookieclientStorage.saveAuthCookie(...); then connects the wallet. No provenance gate.

The clientId domain allowlist does not mitigate this: the malicious link loads the integrator's own allowlisted origin, so every downstream call carries an allowed Origin natively.

Impact class

Phishing link → the victim's browser adopts an attacker-named in-app wallet (any value the victim then deposits or approves flows to the attacker), or an attacker profile is linked onto the victim's account. Pre-conditions are only: <AutoConnect> mounted (default guidance) and the victim opening a link.

Requested change (any one would resolve it)

  1. Provenance gate in the SDK. When initiating a redirect login, persist a one-time nonce and echo it on the return redirectUrl; on load, honor a URL token only if the nonce matches, else ignore/strip it. This is the redirect-OAuth-safe version of "don't trust URL auth material you didn't ask for."
  2. An explicit opt-out, e.g. <AutoConnect readUrlToken={false} /> (or a wallet-level flag), so apps that don't use redirect login can disable URL-token consumption entirely.
  3. At minimum, documented guidance that URL-token consumption is on by default and how to gate it.

Option 2 is the smallest and unblocks apps that use popup/OTP/passkey only.

Context

We implemented an integrator-side guard (a nonce-bound marker set at redirect initiation, stripping any unmatched URL token before <AutoConnect> mounts), so this is not urgent for us, but it belongs in the SDK — most integrators won't know the URL path is load-bearing until they audit it. Happy to share the approach or a PR if useful.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions