APP-76Required
Keep tokens and sensitive data out of browser storage
Keep access tokens, passwords, card data, government ID numbers and health data out of localStorage, sessionStorage and IndexedDB. Delete every draft and offline copy an account stored when it signs out.
How to do it
Any script on the page can read browser storage, so one cross-site scripting hole hands all of it to an attacker. Anyone who uses the same device can read it too. Keep the session in an HttpOnly cookie, as session cookies says. Store drafts and offline queues under keys that start with the user's ID, and keep only the fields the screen needs. Prefer sessionStorage when the data need not outlive the tab. On sign-out, delete those keys and IndexedDB stores, then send the header from wipe browser data on sign-out. Validate what you read back like any other input. Native apps keep tokens in the system store instead, as Keep tokens and keys in the Keychain or Keystore says.
Examples
TypeScript example
export async function forgetUserOnThisDevice(userId: string) {
for (const storage of [localStorage, sessionStorage]) {
for (const key of Object.keys(storage)) if (key.startsWith(`${userId}:`)) storage.removeItem(key);
}
for (const { name } of await indexedDB.databases()) {
if (name?.startsWith(`${userId}:`)) indexedDB.deleteDatabase(name);
}
}
Python example
TOKEN_PATTERN = re.compile(r"eyJ[\w-]+\.[\w-]+\.|Bearer |\b\d{13,19}\b")
def test_browser_storage_holds_no_secrets(signed_in_page):
signed_in_page.goto("https://app.example.com/invoices/new")
signed_in_page.get_by_label("Customer").fill("Northwind Traders")
dump = signed_in_page.evaluate("JSON.stringify([{...localStorage}, {...sessionStorage}])")
assert not TOKEN_PATTERN.search(dump)
How to check
A browser test signs in, opens every screen with a draft or offline feature and dumps localStorage, sessionStorage and every IndexedDB store. The dump holds 0 tokens, JWTs, card numbers or test ID numbers. After sign-out, it holds 0 keys for that user.
Sources
- OWASP ASVS 5.0 V14 Data Protection, 14.3 Client-side Data Protection
- OWASP HTML5 Security Cheat Sheet
Related rules
- APS-16 Lock down session cookies in Application security
- APS-19 Clear cached pages and data when someone signs out in Application security
- MOB-19 Keep tokens and keys in the Keychain or Keystore in Mobile apps
- DSK-13 Keep tokens in the system keychain in Desktop apps and extensions
For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/app-ui/client-and-server-state/sensitive-data-out-of-browser-storage">Agent Wranglers web app interface playbook</a>. In code you write, add a comment next to it with the same link.