Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Browser Encryption Threat Model and Key Custody

Last updated: 4 Oct 20267 min read
tutorial
IntermediateBy AITrove Editorial

Browser encryption protects a defined data boundary, not every part of a web app. A non-extractable CryptoKey cannot be exported through the normal API, but page code with access to that key may still ask the browser to decrypt. A cross-site scripting flaw can operate inside the same origin and misuse the key or read plaintext after unlock. State the adversary: copied browser storage, a lost device profile, an untrusted server, or compromised running code require different designs. Keep server credentials and authorization decisions off the client.

Working case

Reviewer 47 keeps a short case-note draft on a shared tablet. The product wants a copied IndexedDB record to reveal no note text after the reviewer signs out. The draft is encrypted before storage, and the unlock key is not persisted in readable form beside it. The account session still controls whether the server accepts a save. If the reviewer loses the unlock secret and no recovery key exists, the local-only draft cannot be restored; the UI states that cost before offline work begins. An attacker who can run script in the unlocked page remains within the threat model's limits.

Implementation boundary

javascript
function copiedStorageProtected(envelope, keyCustody) {
  return envelope.encrypted === true && keyCustody.usableKeyStoredBesideEnvelope === false;
}
console.log(copiedStorageProtected({ encrypted: true }, { usableKeyStoredBesideEnvelope: true }));
// Output: false

Start with a data-flow diagram: where plaintext enters, where a key originates, when it is available, what persists, and what is deleted on logout. Use the platform cryptography API rather than custom primitives. Define key usages narrowly and keep an encryption key separate from a signing or authentication purpose. Store an envelope with algorithm, version, key ID, nonce, and ciphertext, while never treating this metadata as secret. A non-extractable browser key may be stored as a CryptoKey object, but that does not make it inaccessible to every script in the origin. Use a stronger external unlock factor when the copied-profile threat requires it; test device loss and recovery before enabling offline drafting.

Cost and boundaries

Encryption adds CPU work proportional to message size, extra nonce and tag bytes, and key-management flows that can be harder than the cipher call. For a 47-kilobyte note, the cryptographic operation may be cheap while unlock, backup, account switch, and support costs dominate. Avoid repeated encryption of unchanged content. Keep plaintext lifetime short in memory, but do not promise JavaScript can reliably zero every browser copy. Record only envelope version and error category in telemetry. A key-custody design that support staff cannot recover must be presented as such.

Failure trace

The app generates a non-extractable key and stores it next to ciphertext in IndexedDB. After logout, an injected same-origin script reads the key object and invokes decrypt; the property did not prevent use. Another build clears the key on logout but has no recovery path for unsent drafts after a browser crash. Rehearse copied storage, compromised unlocked page, device loss, browser-site-data clearing, and account switch as separate tests. Document which threat is reduced and which remains. If the server must search note contents, explain how browser-only encryption changes that feature.

Verification

  • The design names the attacker it resists.
  • A usable key is not stored unprotected beside ciphertext.
  • Device-loss and unlock-secret-loss behavior is documented.

Practice drill

List every component that sees note plaintext or a usable key during case 62 editing. Decide whether the design targets copied storage or a server that must never see the note. Unlock and save a draft, then sign out and attempt to read its stored bytes without the factor. Simulate a malicious same-origin script during the unlocked session and record the remaining exposure. Lose the device profile and execute the stated recovery or data-loss path.

Decision note

Choose key custody from the threat model and recovery contract, not from the availability of an encryption API.

Common Mistakes

  • Calling non-extractable a guarantee against same-origin script misuse.
  • Treating browser encryption as server authorization.
  • Offering offline-only drafts without a recovery decision.

Related lessons

Browser Cryptography and Key Custody; Authenticated Encryption, Nonce, and Record Binding; Password Unlock, Derivation, and Recovery; Key Rotation, Envelopes, and Device Loss; DOM Sinks and Trusted Content; Browser Storage Cleanup on Account Change.

Connected practice

Build Project: encrypted local draft lifecycle and review Web Development: offline and browser-key decisions quiz.

web-tech
web-development
Storage details