A vault with corrupt or unreadable metadata is skipped when choosing the next derivation index, so the next vault gets its key #140

Open
opened 2026-10-13 00:30:16 +02:00 by clawbot · 0 comments
Collaborator

Severity: minor
A vault whose vault-metadata.json is corrupt or unreadable is skipped when the next derivation index is chosen, so the next vault created from the same mnemonic gets that vault's index and so the same long-term key; the README's "each vault uses a unique derivation index from the mnemonic, and thus a unique key pair" and "vault isolation" then no longer hold for the two. No data is lost, and the case needs a damaged metadata file.

What happens: GetNextDerivationIndex reads every vault's metadata and continues on a read or parse error, treating the vault as not using any index. The same fail-open shape #51 removed from the unlocker duplicate check.

Reproduction:

export SB_UNLOCK_PASSPHRASE=pw SB_SECRET_MNEMONIC="$M"
secret init; secret vault create work        # work: derivationIndex 1
printf '{' > "$SB_SECRET_STATE_DIR/vaults.d/work/vault-metadata.json"
secret vault create other                     # other: derivationIndex 1
diff "$SB_SECRET_STATE_DIR"/vaults.d/{work,other}/pub.age   # identical

Copying work's unlockers.d entry and current-unlocker into other then opens other's secrets with work's passphrase. chmod 000 on the metadata file gives the same result.

Where:

func GetNextDerivationIndex(
(GetNextDerivationIndex), the two continues at L80 and L88.

Correct behaviour: a vault whose metadata cannot be read or parsed stops vault creation with an error naming the file, as the checks before unlocker add pgp and vault remove already do (TODO.md, 2026-10-03); a missing metadata file in an otherwise complete vault can be treated the same way.

Definition of done

  • vault create and vault import fail, writing nothing, when any vault's metadata file exists but cannot be read or parsed, and the error names the file.
  • A regression test corrupts one vault's metadata, calls CreateVault with the same mnemonic, and requires an error and no new vault; it fails before the fix.

Model: fable-5-1

Severity: minor A vault whose `vault-metadata.json` is corrupt or unreadable is skipped when the next derivation index is chosen, so the next vault created from the same mnemonic gets that vault's index and so the same long-term key; the README's "each vault uses a unique derivation index from the mnemonic, and thus a unique key pair" and "vault isolation" then no longer hold for the two. No data is lost, and the case needs a damaged metadata file. What happens: `GetNextDerivationIndex` reads every vault's metadata and `continue`s on a read or parse error, treating the vault as not using any index. The same fail-open shape https://git.eeqj.de/sneak/secret/issues/51 removed from the unlocker duplicate check. Reproduction: ``` export SB_UNLOCK_PASSPHRASE=pw SB_SECRET_MNEMONIC="$M" secret init; secret vault create work # work: derivationIndex 1 printf '{' > "$SB_SECRET_STATE_DIR/vaults.d/work/vault-metadata.json" secret vault create other # other: derivationIndex 1 diff "$SB_SECRET_STATE_DIR"/vaults.d/{work,other}/pub.age # identical ``` Copying `work`'s `unlockers.d` entry and `current-unlocker` into `other` then opens `other`'s secrets with `work`'s passphrase. `chmod 000` on the metadata file gives the same result. Where: https://git.eeqj.de/sneak/secret/src/commit/ef0ae90768c8b18a829033b3ebd4cf98fcaeb3d1/internal/vault/metadata.go#L37 (`GetNextDerivationIndex`), the two `continue`s at L80 and L88. Correct behaviour: a vault whose metadata cannot be read or parsed stops vault creation with an error naming the file, as the checks before `unlocker add pgp` and `vault remove` already do (`TODO.md`, 2026-10-03); a missing metadata file in an otherwise complete vault can be treated the same way. **Definition of done** - `vault create` and `vault import` fail, writing nothing, when any vault's metadata file exists but cannot be read or parsed, and the error names the file. - A regression test corrupts one vault's metadata, calls `CreateVault` with the same mnemonic, and requires an error and no new vault; it fails before the fix. Model: fable-5-1
sneak was assigned by clawbot 2026-10-13 00:30:17 +02:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/secret#140