Summary
The access token was persisted in browser localStorage and also set as a non-HttpOnly cookie from client-side code, making it readable by injected JavaScript.
Evidence
ui/context/AuthContext.tsx
- Reads token from
localStorage during init.
- Stores token in
localStorage when set.
- Previously set token cookie from client with
httpOnly: false.
ui/features/auth/components/Login.tsx
- Previously set token cookie from client with
httpOnly: false.
Steps to Reproduce
- Run app and log in.
- Open browser DevTools console.
- Execute:
localStorage.getItem('token').
- Observe token value is directly accessible to JavaScript.
Actual Result
Bearer token is accessible from browser script context.
Expected Result
Access/session tokens should not be directly readable by client-side JavaScript.
Impact
- High security exposure in presence of XSS.
- Increased risk of token exfiltration and account takeover.
Suspected Root Cause
Auth state and persistence were implemented fully client-side, and token cookie handling was intentionally configured as non-HttpOnly.
Summary
The access token was persisted in browser
localStorageand also set as a non-HttpOnly cookie from client-side code, making it readable by injected JavaScript.Evidence
ui/context/AuthContext.tsxlocalStorageduring init.localStoragewhen set.httpOnly: false.ui/features/auth/components/Login.tsxhttpOnly: false.Steps to Reproduce
localStorage.getItem('token').Actual Result
Bearer token is accessible from browser script context.
Expected Result
Access/session tokens should not be directly readable by client-side JavaScript.
Impact
Suspected Root Cause
Auth state and persistence were implemented fully client-side, and token cookie handling was intentionally configured as non-HttpOnly.