Skip to content

token localstorage hardening security review#509

Open
cubap wants to merge 2 commits intomainfrom
402-token-localstorage-hardening-review
Open

token localstorage hardening security review#509
cubap wants to merge 2 commits intomainfrom
402-token-localstorage-hardening-review

Conversation

@cubap
Copy link
Member

@cubap cubap commented Mar 10, 2026

Gate 4.2 — Token/localStorage hardening

Full audit of all localStorage usage across the interfaces repo, with three targeted fixes implemented on branch 402-token-localstorage-hardening-review.

Threat surface documented:

Key Owner Risk
userToken api/TPEN.js JWT in localStorage; XSS-accessible. Expiry checked on every read via checkExpired(). Primary mitigations applied below.
vault:* js/vault.js IIIF resources cached indefinitely. All data is open/public in RERUM — no cross-user privacy concern; cache intentionally preserved across user switches to avoid unnecessary network reloads.
tpen-drafts:{project}:{page} components/transcription-block Well-scoped already. No change needed.
annotationsState interfaces/manage-columns Unscoped flat key; now scoped with project ID.

Changes in this PR:

  1. Token expiration UX (api/TPEN.js constructor) — previously expiry only added a .expired CSS class with no user notification. Now dispatches a tpen-toast error and calls TPEN.login() after 4 s, ensuring users are always redirected to log in again.

  2. TPEN.getAuthorization() in TPEN 2.8 import flow (components/new-action.js) — replaced raw localStorage.getItem("userToken") with TPEN.getAuthorization(), which runs the expiry check before use. If the token is expired the handler redirects to login rather than proceeding with a stale token.

  3. annotationsState key scoped with project ID (interfaces/manage-columns/index.js) — all five read/write/remove calls now use `annotationsState:${TPEN.screen.projectInQuery ?? 'unknown'}` to prevent any cross-project state bleed.

Residual risks noted for threat model (require TPEN3/services coordination):

  • JWT still stored in localStorage (vs. HttpOnly cookie) — this is an architectural decision owned by the TPEN3 auth flow; mitigated here by expiry enforcement and expiration UX redirect.

@github-actions
Copy link
Contributor

@cubap cubap requested a review from thehabes March 10, 2026 18:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant