Threat model, 2026: browsers and extensions
Scheduled8 min read By NT²
Threat models age with browsers. This 2026 refresh keeps the residual risks named—XSS, unlocked theft, hostile extensions, origin supply chain—and checks which defenses still hold when the client world moves.
Threat model, 2026: browsers and extensions
Claim: a threat model needs a calendar
In late 2026 we publish a refresh of the threat model we already named in public: XSS steals sessions elsewhere; here keys are non-extractable. That first essay was evergreen on purpose. This one is dated on purpose.
Browsers ship new permission prompts, new extension packaging rules, new defaults for third-party cookies, and new ways for “helpful” tooling to touch the same origin as a password vault. The client supply chain—npm packages that land in the vault JavaScript bundle, WASM loaders, build plugins—keeps inventing quieter ways to put foreign script next to your ciphertext. None of that rewrites cryptography. All of it changes where residual risk concentrates.
So the claim for this year is:
The 2026 threat model is the same architecture under a moving browser and extension sky: unlocked-session failure stays local and time-bounded; the edge still refuses unlock oracles; we do not pretend the year made XSS or hostile extensions disappear.
If last year’s essay answered “what still hurts,” this one answers “what moved around the hurt—and what we still refuse to paper over.”
Constraint: the client world changed; the JavaScript world did not
Three constraints still bind. Two of them got louder in 2026.
Same-origin script is still the vault. Whatever can run JavaScript in the unlocked vault page can call the same Web Cryptography API surfaces the product uses. Non-extractable CryptoKey handles still refuse exportKey. They still allow encrypt / decrypt while the handle is live. That invariant did not soften because a browser vendor shipped a prettier lock icon. XSS while unlocked remains a serious bug class—not a solved category.
What did change is how often “script in the origin” arrives without looking like classic XSS. Dependency updates that pull a compromised transitive package into the vault bundle. Build tooling that injects telemetry “for diagnostics.” Browser features that make side-loading or enterprise-managed extensions easier to distribute at scale. The constraint is unchanged: if it runs as the vault origin, it shares the unlocked session. The attack packaging got more corporate and more plausible.
Extensions remain a privileged neighbor. Chromium-family and other browsers still grant extensions powers that ordinary websites do not have—content scripts, broad host permissions, optional access that users click through because a store listing promised productivity. Review pipelines improve and regress in cycles; none of them make a vault immune to an extension that can inject into se.nt2.me. In 2026 the useful honesty is sharper: extension risk is not “maybe someday.” For a zero-knowledge vault, a hostile or over-privileged extension with script access to the vault origin is effectively XSS with a store badge. Architecture can shrink what that attacker can export; it cannot rewrite the browser’s trust model for add-ons.
Device theft while unlocked is still physics. Auto-lock shortens the window. OS lock, screen privacy, and not leaving a warm session at a café remain user-side controls. New browser “continue where you left off” comfort features are a product temptation we treat as hostile to vault memory hygiene—not as a free unlock UX win.
The edge constraint did not drift: master password never leaves the browser; KDF salt and password verifier stay on the device; cloud identity proves a cryptographic vault identity without holding unlock ingredients. Client compromise for one unlocked window must not upgrade into a provider password reset or a cloud guessing oracle. That refusal is older than this refresh and still the load-bearing half of Null Trust².
Design: refresh the map, keep the refusals
We are not rewriting the threat model from a blank page. We are re-checking the map against 2026 client reality.
| Surface (2026) | What still works against you | What stayed the same in the design |
|---|---|---|
| XSS / same-origin script while unlocked | Use live CryptoKeys; read decrypted UI; call APIs the page can call | Non-extractable vault AES keys; no silent rehydrate after refresh; lean vault origin (no tracking SDKs) |
| Malicious or over-privileged extension | Same class as XSS for origins it can inject | Treat extension access as in-scope residual risk; do not market “store reviewed = safe for vaults” |
| Client supply chain (dependency / build) | Foreign code in the vault bundle shares the unlocked session | Prefer minimal client deps; security veto on “helpful” extractable keys, salt escrow, forgot-password patches |
| Device theft / warm session | Read the screen; operate the unlocked UI until idle clear | Idle clear (~5 minutes), refresh → null, tab close ends the session |
| Compromised operator / edge | Ciphertext, public identifiers, blind metadata | No master password, salt, verifier, or support reset that reconstructs unlock |
flowchart TB
subgraph year [What moved in 2026]
Ext[Extension packaging and prompts]
Dep[Client dependency and build surface]
UX[Browser continuity and comfort features]
end
subgraph hold [What must still hold]
Key[Non-extractable CryptoKey in memory]
Idle[Idle / refresh / close clear to null]
Blind[Edge without unlock oracles]
end
Ext --> Key
Dep --> Key
UX --> Idle
Key --> Blind
Idle --> Blind
Session policy is still memory hygiene, not a comfort timer. Unlock derives a vault AES key with extractable: false, holds it in in-memory application state, and clears it on explicit lock, roughly five minutes without input, hard refresh, and tab close. That story is unchanged in substance; it is restated here because browser “session restore” culture keeps pushing the opposite instinct. Detail lives in Auto-lock is a memory hygiene problem.
Supply-chain discipline is the year-specific emphasis. A password vault’s threat model is incomplete if it only talks about strangers on the network. Code that ships into the vault origin is part of the trusted computing base whether it came from a hand-written module or a transitive package. We refuse third-party tracking and widget scripts on the vault origin for that reason—not because analytics are impolite, but because every extra script is another neighbor in the unlocked session. Process-side, “just this once” patches that reintroduce extractable keys or a cloud recovery oracle get a security veto, not a merge debate vibe—see Security veto is a role, not a vibe.
Operators still cannot “fix” the user’s machine. We can keep the edge blind. We cannot uninstall a user’s hostile extension, patch every browser CVE the day it ships, or invent a secure enclave inside every WebView. Offline-first design helps here in a quiet way: the happy path does not require a live network session that an attacker can also abuse as a remote control channel—Offline-capable is not sync later if lucky—but offline does not mean “immune to local script.”
Trade-off: annual honesty vs. evergreen slogans
Publishing a dated threat model costs marketing smoothness. Evergreen copy prefers “military-grade encryption” forever. A year stamp invites the awkward question: did something break?
Sometimes the honest answer is: the environment moved, not the promise. Extension stores rotate policies. Browsers add continuity features that would love to keep secrets warm across restarts. The JavaScript ecosystem keeps proving that “we only import trusted packages” is a process, not a one-time checkbox. Naming those shifts without inventing CVE theater or competitor scare pieces is the editorial trade-off: specific enough to be useful, boring enough to stay true.
Users still pay friction. Idle auto-lock interrupts long reading sessions. Refresh mid-edit means unlock again. Declining a kitchen-sink of browser extensions is user work we cannot cryptographically delete. Reviewers who want “therefore safe in 2026” will still be disappointed: XSS while unlocked can still decrypt; theft while unlocked can still read; an over-privileged extension can still act as the page.
What we get back is a failure mode that still matches the brand. When the client is wrong, the edge does not become a second vault owner—No password reset, by design. When the session ends, the live key is gone—not parked as a string-shaped secret. When an attacker has script in the unlocked page, they still cannot casually export vault AES material for offline reuse elsewhere. Smaller blast radius. Not a magic shield. That naming is Null Trust² — what the name means.
What we refuse (still, in 2026)
Architecture is clearer when the refusals survive a calendar flip.
We refuse extractable vault AES keys in the unlocked session. If the browser can export the key, same-origin script—and an injecting extension—can too.
We refuse treating XSS or extension injection as “solved” by encryption at rest. Ciphertext on disk does not protect a live memory handle. Mitigations remain short sessions, non-extractable keys, and a lean origin.
We refuse provider password reset and cloud-held unlock oracles. A 2026 client compromise must not upgrade into “email support for a new key that opens old ciphertext.”
We refuse third-party tracking and widget scripts on the vault origin that widen the script surface dependency risk or an attacker can abuse.
We refuse marketing invincibility for a new browser year. New prompts and store badges do not delete residual risk. Device theft while unlocked, malicious extensions with page access, XSS while unlocked, and a poisoned dependency in the vault bundle remain real.
We refuse “remember this device” rehydration of live AES material—including whatever continuity feature a browser invents next—so unlock friction never becomes silent re-entry.
We refuse CVE theater and competitor scare pieces as a substitute for a threat model. Fear is not a boundary diagram.
Close: companions, then a quiet ask
This refresh sits beside the first-pass model, not on top of it. Read XSS steals sessions elsewhere; here keys are non-extractable for the evergreen claim. For memory hygiene, Auto-lock is a memory hygiene problem. For how refusals stay shippable under agent velocity, Security veto is a role, not a vibe. For recovery honesty, No password reset, by design. For the brand constraint, Null Trust² — what the name means. For why the happy path stays local, Offline-capable is not sync later if lucky.
Browsers will keep moving. Extensions will keep asking for more. The useful vault threat model is the one that ages in public: what changed, what held, what still hurts—and what operators still cannot fix for you.
If that 2026 reading matches how you want a private vault to fail—narrowly, locally, without a provider back door—you can try NT² Vault or read more at nt2.me.
Last updated 2026-11-08
Related stories
- XSS steals sessions elsewhere; here keys are non-extractable
8 min read
- Wrong password must fail closed
8 min read
- Auto-lock is a memory hygiene problem
9 min read