Locations
Summary
A SIWE response can install account A's bearer token after the connected wallet has changed to account B. The application then renders for B while authenticated to the Survey API as A.
Root cause
SiweAuthProvider.signIn retains the setToken callback associated with the address captured when the request began and invokes it without confirming that the address is still current. useSessionStorage setters update one shared React state value even when their captured storage key is obsolete.
- The stale setter correctly writes the credential to A's storage key but also unconditionally replaces the currently exposed token.
- If A's response arrives after the key-change effect has loaded B's slot, no later effect restores B's value.
Impact
A user interacting under wallet B can inherit A's bearer credential without controlling A's key at that time. Valid requests are consequently authorized with A's Survey API permissions: for example, delegates/my exposes A's delegated operators and enables setup reads or mutations that A—not B—is authorized to perform.
The affected state is off-chain and correctable, and reloading or changing the storage key restores the proper session, so severity is low.
Scenario
- Account A starts SIWE authentication and signs the address-bound message.
- Before
/auth/signin returns, the wallet changes to account B.
- The session-storage effect loads B's normally empty token slot.
- A's delayed sign-in response invokes A's captured setter, which writes A's token into the shared React state.
SiweAuthGate opens under B's wallet state, while authenticated Survey API requests carry A's valid bearer token.
- The B-rendered UI can read or mutate resources covered by A's API authority until the session state is resynchronized.
Drafted from LidoLens finding SURVEY-SIWE-01
Locations
csm-widget/modules/siwe/siwe-auth-provider.tsx:63-69csm-widget/shared/hooks/use-session-storage.ts:54-72Summary
A SIWE response can install account A's bearer token after the connected wallet has changed to account B. The application then renders for B while authenticated to the Survey API as A.
Root cause
SiweAuthProvider.signInretains thesetTokencallback associated with the address captured when the request began and invokes it without confirming that the address is still current.useSessionStoragesetters update one shared React state value even when their captured storage key is obsolete.Impact
A user interacting under wallet B can inherit A's bearer credential without controlling A's key at that time. Valid requests are consequently authorized with A's Survey API permissions: for example,
delegates/myexposes A's delegated operators and enables setup reads or mutations that A—not B—is authorized to perform.The affected state is off-chain and correctable, and reloading or changing the storage key restores the proper session, so severity is low.
Scenario
/auth/signinreturns, the wallet changes to account B.SiweAuthGateopens under B's wallet state, while authenticated Survey API requests carry A's valid bearer token.Drafted from LidoLens finding SURVEY-SIWE-01