Skip to content

token localstorage hardening security review#509

Merged
thehabes merged 4 commits intomainfrom
402-token-localstorage-hardening-review
Mar 16, 2026
Merged

token localstorage hardening security review#509
thehabes merged 4 commits intomainfrom
402-token-localstorage-hardening-review

Conversation

@cubap
Copy link
Copy Markdown
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
Copy Markdown
Contributor

github-actions bot commented Mar 10, 2026

@cubap cubap requested a review from thehabes March 10, 2026 18:47
Copy link
Copy Markdown
Member

@thehabes thehabes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added an extra guard for the projectID/pageID url variables. Also guarded against logout time and login function stacking.

@thehabes thehabes merged commit 6059864 into main Mar 16, 2026
3 checks passed
@thehabes thehabes deleted the 402-token-localstorage-hardening-review branch March 16, 2026 17:36
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.

2 participants