Where.src/shared/vault.js:86-93 and 113-120 (crypto_pwhash with OPSLIMIT_INTERACTIVE / MEMLIMIT_INTERACTIVE); src/popup/views/addWallet.js:116
(the 12-character minimum password).
The question. The profile is stored unencrypted in extension storage except
for wallets[].encryptedSecret, so the key-derivation cost and the password
policy are the only protection of a stolen profile. vault.js deliberately uses
INTERACTIVE (2 passes, 64 MiB, ~150 ms) because the password is entered on every
signature and a heavier cost would slow every signature. libsodium recommends
MODERATE (3 passes, 256 MiB) or SENSITIVE for data at rest.
Options.
Keep INTERACTIVE and record the reasoning in README Key Decisions (the
per-signature UX cost is the reason).
Move to MODERATE (~0.5–1 s per signature) and re-encrypt each secret on the
next successful unlock.
Recommendation. Document the current choice in README Key Decisions. A
per-signature password prompt is a real UX constraint that argues for
INTERACTIVE, and the 12-character minimum is the lever that matters more for a
stolen profile — so raising the minimum (and rejecting weak passwords) may be a
better return than the KDF cost.
Definition of done.
The owner rules keep vs raise the parameters.
If kept: README Key Decisions states the parameters and why (the
per-signature cost).
If raised: the new parameters are set, existing secrets are re-encrypted on
the next unlock, and the README is updated.
Model: fable-5-1 (review); opus-4-8 (filing)
Severity: hardening. Owner decision.
**Where.** `src/shared/vault.js:86-93` and `113-120` (`crypto_pwhash` with
`OPSLIMIT_INTERACTIVE` / `MEMLIMIT_INTERACTIVE`); `src/popup/views/addWallet.js:116`
(the 12-character minimum password).
**The question.** The profile is stored unencrypted in extension storage except
for `wallets[].encryptedSecret`, so the key-derivation cost and the password
policy are the only protection of a stolen profile. `vault.js` deliberately uses
INTERACTIVE (2 passes, 64 MiB, ~150 ms) because the password is entered on every
signature and a heavier cost would slow every signature. libsodium recommends
MODERATE (3 passes, 256 MiB) or SENSITIVE for data at rest.
**Options.**
- Keep INTERACTIVE and record the reasoning in README Key Decisions (the
per-signature UX cost is the reason).
- Move to MODERATE (~0.5–1 s per signature) and re-encrypt each secret on the
next successful unlock.
**Recommendation.** Document the current choice in README Key Decisions. A
per-signature password prompt is a real UX constraint that argues for
INTERACTIVE, and the 12-character minimum is the lever that matters more for a
stolen profile — so raising the minimum (and rejecting weak passwords) may be a
better return than the KDF cost.
**Definition of done.**
- [ ] The owner rules keep vs raise the parameters.
- [ ] If kept: README Key Decisions states the parameters and why (the
per-signature cost).
- [ ] If raised: the new parameters are set, existing secrets are re-encrypted on
the next unlock, and the README is updated.
Model: fable-5-1 (review); opus-4-8 (filing)
clawbot
added this to the 1.0.0 milestone 2026-09-21 20:37:56 +02:00
sneak
was assigned by clawbot2026-09-21 20:37:56 +02:00
Ask: should the password hashing that protects the stored recovery phrase stay at libsodium's fast setting (64 MiB, about 0.15 s on every signature) or move to its stronger at-rest setting (256 MiB, roughly 0.5 to 1 s on every signature)? Recommendation: keep the fast setting and write the reason into README.md Key Decisions; against a stolen profile, the 12-character minimum password matters more.
Model: opus-5-5
Ask: should the password hashing that protects the stored recovery phrase stay at libsodium's fast setting (64 MiB, about 0.15 s on every signature) or move to its stronger at-rest setting (256 MiB, roughly 0.5 to 1 s on every signature)? Recommendation: keep the fast setting and write the reason into `README.md` Key Decisions; against a stolen profile, the 12-character minimum password matters more.
Model: opus-5-5
Can we use the long one on first signature/pw entry then cache in ram only what we need to do a faster one on subsequent passphrase entries? The threat model against stolen secrets from disk and stolen secrets from ram is vastly different.
Can we use the long one on first signature/pw entry then cache in ram only what we need to do a faster one on subsequent passphrase entries? The threat model against stolen secrets from disk and stolen secrets from ram is vastly different.
sneak
was unassigned by clawbot2026-10-21 12:08:49 +02:00
clawbot
self-assigned this 2026-10-21 12:08:49 +02:00
On disk (extension local storage, as today): each wallet's secret encrypted under a key derived from the password at libsodium's strongest setting, SENSITIVE (1 GiB, 4 passes). Nothing else secret is ever written.
First password entry for a wallet after the browser starts (signing, showing the phrase, anything): the slow derivation decrypts the secret, about 6 seconds measured here (MODERATE, 256 MiB, takes about 1.3 s). The wallet then encrypts the secret again under a second key, derived from the same password with a fresh salt at today's fast setting (64 MiB, 2 passes), and keeps only that copy in the browser's session storage. Creating or importing a wallet does both at once.
Every later entry decrypts the session copy in about 0.15 s, as today. The password is still asked for on every signature, and a wrong one is refused just as fast.
How long the memory copy lasts: until the browser closes or the extension is reloaded or updated, and it is removed when its wallet is deleted. Session storage is held in memory and never written to disk by Chrome or Firefox (the operating system can still swap any memory out, as it can the decrypted secret while a transaction is signed today).
Stolen profile: only the strong copy. Each password guess costs about 30 times the work it costs today and needs 1 GiB of memory, which also limits how many guesses a GPU can run at once.
Memory dump of a running browser after the first entry: the session copy, guessable at today's cost per guess, so no worse than a stolen profile is now. Someone who can read the browser's memory can also catch the password or the secret during the next signature, so the copy gives that attacker little more.
Recommendation: build this with SENSITIVE on disk. If either browser refuses the 1 GiB allocation in the popup, MODERATE is used instead; the browser test settles which. The 12-character minimum stays.
Model: opus-5-5
Yes. Design:
- **On disk** (extension local storage, as today): each wallet's secret encrypted under a key derived from the password at libsodium's strongest setting, SENSITIVE (1 GiB, 4 passes). Nothing else secret is ever written.
- **First password entry for a wallet after the browser starts** (signing, showing the phrase, anything): the slow derivation decrypts the secret, about 6 seconds measured here (MODERATE, 256 MiB, takes about 1.3 s). The wallet then encrypts the secret again under a second key, derived from the same password with a fresh salt at today's fast setting (64 MiB, 2 passes), and keeps only that copy in the browser's session storage. Creating or importing a wallet does both at once.
- **Every later entry** decrypts the session copy in about 0.15 s, as today. The password is still asked for on every signature, and a wrong one is refused just as fast.
- **How long the memory copy lasts:** until the browser closes or the extension is reloaded or updated, and it is removed when its wallet is deleted. Session storage is held in memory and never written to disk by Chrome or Firefox (the operating system can still swap any memory out, as it can the decrypted secret while a transaction is signed today).
- **Stolen profile:** only the strong copy. Each password guess costs about 30 times the work it costs today and needs 1 GiB of memory, which also limits how many guesses a GPU can run at once.
- **Memory dump of a running browser after the first entry:** the session copy, guessable at today's cost per guess, so no worse than a stolen profile is now. Someone who can read the browser's memory can also catch the password or the secret during the next signature, so the copy gives that attacker little more.
Recommendation: build this with SENSITIVE on disk. If either browser refuses the 1 GiB allocation in the popup, MODERATE is used instead; the browser test settles which. The 12-character minimum stays.
Model: opus-5-5
clawbot
removed their assignment 2026-10-21 20:36:40 +02:00
sneak
was assigned by clawbot2026-10-21 20:36:40 +02:00
No, this is ridiculously inappropriate memory usage for a browser extension. Also this is all too complicated. The length of the passphrase is what protects the storage. A reasonable (100ms) kdf is ok but don’t use so much memory.
Also, the user should be able to set a weak passphrase if they REALLY want to, but “allow weak passphrases” should be disabled in prefs.
No, this is ridiculously inappropriate memory usage for a browser extension. Also this is all too complicated. The length of the passphrase is what protects the storage. A reasonable (100ms) kdf is ok but don’t use so much memory.
Also, the user should be able to set a weak passphrase if they REALLY want to, but “allow weak passphrases” should be disabled in prefs.
Recorded: the two-step design above is dropped as too heavy and too complicated. The passphrase's length is what protects the stored secret.
My reading, for you to confirm before anything is built:
Key derivation stays as it is today: one derivation of about a tenth of a second (libsodium's interactive setting, 64 MiB, about 0.15 s), with no second copy in memory.
The 12-character minimum stays the default.
A new setting, "allow weak passphrases", off by default, lets a user who turns it on set a shorter passphrase.
Question: is today's 64 MiB setting what you mean by a reasonable derivation, or should it use less memory? Recommendation: keep today's setting; it is the light one, and nothing about it changes.
Model: opus-5-5
Recorded: the two-step design above is dropped as too heavy and too complicated. The passphrase's length is what protects the stored secret.
My reading, for you to confirm before anything is built:
- Key derivation stays as it is today: one derivation of about a tenth of a second (libsodium's interactive setting, 64 MiB, about 0.15 s), with no second copy in memory.
- The 12-character minimum stays the default.
- A new setting, "allow weak passphrases", off by default, lets a user who turns it on set a shorter passphrase.
Question: is today's 64 MiB setting what you mean by a reasonable derivation, or should it use less memory? Recommendation: keep today's setting; it is the light one, and nothing about it changes.
Model: opus-5-5
Recorded. The work is #674: the "Allow weak passphrases" setting, off by default; key derivation and the 12-character default stay as they are.
Model: opus-5-5
Recorded. The work is https://git.eeqj.de/sneak/AutistMask/issues/674: the "Allow weak passphrases" setting, off by default; key derivation and the 12-character default stay as they are.
Model: opus-5-5
sneak
was unassigned by clawbot2026-10-25 03:07:30 +01:00
clawbot
self-assigned this 2026-10-25 03:07:30 +01:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Severity: hardening. Owner decision.
Where.
src/shared/vault.js:86-93and113-120(crypto_pwhashwithOPSLIMIT_INTERACTIVE/MEMLIMIT_INTERACTIVE);src/popup/views/addWallet.js:116(the 12-character minimum password).
The question. The profile is stored unencrypted in extension storage except
for
wallets[].encryptedSecret, so the key-derivation cost and the passwordpolicy are the only protection of a stolen profile.
vault.jsdeliberately usesINTERACTIVE (2 passes, 64 MiB, ~150 ms) because the password is entered on every
signature and a heavier cost would slow every signature. libsodium recommends
MODERATE (3 passes, 256 MiB) or SENSITIVE for data at rest.
Options.
per-signature UX cost is the reason).
next successful unlock.
Recommendation. Document the current choice in README Key Decisions. A
per-signature password prompt is a real UX constraint that argues for
INTERACTIVE, and the 12-character minimum is the lever that matters more for a
stolen profile — so raising the minimum (and rejecting weak passwords) may be a
better return than the KDF cost.
Definition of done.
per-signature cost).
the next unlock, and the README is updated.
Model: fable-5-1 (review); opus-4-8 (filing)
clawbot referenced this issue2026-10-03 14:20:50 +02:00
Ask: should the password hashing that protects the stored recovery phrase stay at libsodium's fast setting (64 MiB, about 0.15 s on every signature) or move to its stronger at-rest setting (256 MiB, roughly 0.5 to 1 s on every signature)? Recommendation: keep the fast setting and write the reason into
README.mdKey Decisions; against a stolen profile, the 12-character minimum password matters more.Model: opus-5-5
Can we use the long one on first signature/pw entry then cache in ram only what we need to do a faster one on subsequent passphrase entries? The threat model against stolen secrets from disk and stolen secrets from ram is vastly different.
Yes. Design:
Recommendation: build this with SENSITIVE on disk. If either browser refuses the 1 GiB allocation in the popup, MODERATE is used instead; the browser test settles which. The 12-character minimum stays.
Model: opus-5-5
No, this is ridiculously inappropriate memory usage for a browser extension. Also this is all too complicated. The length of the passphrase is what protects the storage. A reasonable (100ms) kdf is ok but don’t use so much memory.
Also, the user should be able to set a weak passphrase if they REALLY want to, but “allow weak passphrases” should be disabled in prefs.
Recorded: the two-step design above is dropped as too heavy and too complicated. The passphrase's length is what protects the stored secret.
My reading, for you to confirm before anything is built:
Question: is today's 64 MiB setting what you mean by a reasonable derivation, or should it use less memory? Recommendation: keep today's setting; it is the light one, and nothing about it changes.
Model: opus-5-5
confirmed and recommendation approved.
Recorded. The work is #674: the "Allow weak passphrases" setting, off by default; key derivation and the 12-character default stay as they are.
Model: opus-5-5