create_account persists the generated nsec as plaintext hex in the config file #58

Open
opened 2026-10-09 17:18:03 +00:00 by padreug · 0 comments
Owner

src/daemon/admin/commands/create_account.ts:204 writes currentConfig.keys[keyName] = { key: Buffer.from(sk).toString('hex') } and run.ts:213-222 loads such entries unencrypted at boot. Keys created via add / create_new_key go through encryptNsec; signup keys bypass encryption-at-rest entirely and leave two storage formats the loader treats differently.

Impact: on any deployment that enables the signup flow, one config-file disclosure is a full key compromise for every hosted account. (Our create_new_key path is not affected.)

Fix direction: route signup keys through encryptNsec under the daemon's autounlock master secret (NSEC_BUNKER_AUTOUNLOCK_PASSPHRASE[_FILE], already resolved in run.ts maybeAutounlock), and fail closed — refuse the signup — when no master secret is configured. Unify the stored shape so the loader never accepts a raw {key}. Sandbox PR sandbox-team/nsecbunkerd#25 commit 2 (resolveMasterPassphrase shared by autounlock and create_account, tests/account-key-encryption.test.ts) is a ready port. Do this together with or after the KDF/AEAD fix.

Found during reforge run #1 (sandbox nsecbunkerd#6).

`src/daemon/admin/commands/create_account.ts:204` writes `currentConfig.keys[keyName] = { key: Buffer.from(sk).toString('hex') }` and `run.ts:213-222` loads such entries unencrypted at boot. Keys created via `add` / `create_new_key` go through `encryptNsec`; signup keys bypass encryption-at-rest entirely and leave two storage formats the loader treats differently. Impact: on any deployment that enables the signup flow, one config-file disclosure is a full key compromise for every hosted account. (Our `create_new_key` path is not affected.) Fix direction: route signup keys through `encryptNsec` under the daemon's autounlock master secret (`NSEC_BUNKER_AUTOUNLOCK_PASSPHRASE[_FILE]`, already resolved in `run.ts maybeAutounlock`), and fail closed — refuse the signup — when no master secret is configured. Unify the stored shape so the loader never accepts a raw `{key}`. Sandbox PR sandbox-team/nsecbunkerd#25 commit 2 (`resolveMasterPassphrase` shared by autounlock and create_account, `tests/account-key-encryption.test.ts`) is a ready port. Do this together with or after the KDF/AEAD fix. Found during reforge run #1 (sandbox nsecbunkerd#6).
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
aiolabs/nsecbunkerd#58
No description provided.