diff --git a/SECURITY.md b/SECURITY.md index 7514e1b7..9c137c78 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,14 +1,30 @@ # Security -codex32 handles wallet recovery material. Use a trusted computer and have the -software and recovery plan reviewed before relying on it with funds. For -stronger isolation, use codex32 and the Bitcoin Core signing wallet only on a -computer kept permanently offline. +codex32 handles wallet backup and recovery secrets. Have the software and +recovery plan reviewed before using real funds. + +## Trusted computer + +A **trusted computer** is one you exclusively control, believe is free of +malware, and whose operating system and other software you trust. Use one for +backup creation, recovery, wallet setup, and signing. + +Follow [Bitcoin Core's wallet-encryption guidance][core-wallet]. Encryption +[cannot fully protect your bitcoins from malware][core-dialog]. Keep your +wallet passphrase safe. + +For stronger isolation, use an offline signing computer that never connects to +any network, including Ethernet, internet, Tor, Wi-Fi, Bluetooth, or cellular, +as in [Bitcoin Core's offline-signing tutorial][core-offline]. Online Core nodes +must synchronize before their balances or history are trusted. A valid checksum detects many copying mistakes. It does not prove that a backup belongs to your wallet. A correction is only a suggestion; compare it with the physical backup and wallet information kept elsewhere. +codex32 is designed to avoid accidental disclosure; commands display recovery +material only when that is their purpose. + Python, your terminal, and your operating system may retain secret text in memory or scrollback. codex32 does not intentionally save secrets and keeps them out of command arguments and normal machine output, but it cannot @@ -16,6 +32,10 @@ guarantee that every copy is erased from swap, hibernation data, or crash dumps. Using Tails and shutting down when finished helps mitigate this Python limitation. +[core-wallet]: https://github.com/bitcoin/bitcoin/blob/v32.0/doc/managing-wallets.md#12-encrypting-the-wallet +[core-dialog]: https://github.com/bitcoin/bitcoin/blob/v32.0/src/qt/askpassphrasedialog.cpp +[core-offline]: https://github.com/bitcoin/bitcoin/blob/v32.0/doc/offline-signing-tutorial.md + ## Report a security problem Send vulnerability reports privately to the maintainer address in diff --git a/docs/security/invariants.md b/docs/security/invariants.md index be5ed482..24fde0a9 100644 --- a/docs/security/invariants.md +++ b/docs/security/invariants.md @@ -31,8 +31,11 @@ and evidence. warning and literal `YES` confirmation for every HRP. The bound includes all admitted classes ranked equal to or better than the candidate, independently of execution order. -6. Secrets stay out of arguments, logs, ordinary output, and public transfers. +6. Secrets stay out of command arguments, logs, unrelated output, and public + transfers. Only commands intended to produce recovery material may display it. During wallet setup, codex32 transfers the master xprv only through child stdin. + Timestamped rescans capture Core's private descriptor output and return it + through child stdin, never command arguments or operator output. 7. Bitcoin Core chains are discovered before entropy or recovery input. The operator confirms an eligible descriptor wallet by exact name. 8. Wallet state is revalidated before handing Core the master key. Core must @@ -41,10 +44,7 @@ and evidence. and verified on every exit path. 10. External text, Core output, public wallet data, and PSBTs are untrusted. 11. Only Bitcoin Core descriptor wallets sign with codex32-derived keys. - Sensitive operations use only codex32 or Core on malware-free computers - with trusted software. -12. Offline hosts disable every network path, including Ethernet, internet, - Tor, Wi-Fi, Bluetooth, and cellular. Online Core nodes synchronize before - their balances or history are trusted. +12. Computer and network use follows the requirements in + [SECURITY.md](../../SECURITY.md#trusted-computer). Changes require matching model, tests, and security-review evidence. diff --git a/docs/security/model.md b/docs/security/model.md index de77db4d..4b4ca22d 100644 --- a/docs/security/model.md +++ b/docs/security/model.md @@ -35,14 +35,9 @@ The operator must: - use only Bitcoin Core descriptor wallets to sign with keys derived from a codex32 master seed; -- use computers believed malware-free and whose other software is trusted for - all codex32 operations and for wallet initialization and signing with Bitcoin - Core; -- disconnect every computer used for offline codex32 or signing work from all - network paths, including Ethernet, internet, Tor, Wi-Fi, Bluetooth, and - cellular; -- synchronize Bitcoin Core on the networked computer before trusting its - balances or history; +- follow the [computer requirements](../../SECURITY.md#trusted-computer) for all + operations involving recovery material, including wallet initialization and + signing with Bitcoin Core; - protect recovery cards and store shared cards in different trusted places; - confirm every newly recorded secret or share; - keep wallet records separate from shares, type the master fingerprint from diff --git a/docs/user/guide.md b/docs/user/guide.md index 422ec998..a4edbb8a 100644 --- a/docs/user/guide.md +++ b/docs/user/guide.md @@ -87,16 +87,14 @@ codex32 detects and reports the local Bitcoin Core network. You do not need to change `bitcoin.conf` when using the standard local data directory and RPC port. -Use a computer you believe is malware-free and whose other software you trust. -Only codex32 and Bitcoin Core should perform recovery, derivation, wallet -initialization, or signing. The QR tools below transport only public -descriptors or PSBTs. +Use a [trusted computer](../../SECURITY.md#trusted-computer) for backup, +recovery, and signing. Bitcoin Core wallet encryption is strongly recommended. Bitcoin Core owns the passphrase and its prompts; codex32 never asks for, reads, or forwards it. -Do not type recovery text on the same line as a command. Run the command first, -then enter a master seed or shares on the separate `>` line when prompted. +Run the command first, then type your seed or shares at the `>` prompt. Never +put recovery text in the command itself: your shell may save that text. This keeps a 48-character string grouped in fours within an 80-column terminal. Later share prompts may show a fixed common header after `>`. Never photograph recovery text or put it in a website, chat, cloud clipboard, or online QR diff --git a/src/codex32/_cli_parser.py b/src/codex32/_cli_parser.py index c2472109..05912fdd 100644 --- a/src/codex32/_cli_parser.py +++ b/src/codex32/_cli_parser.py @@ -86,7 +86,7 @@ def parser(prog: str = "codex32", *, master_seed: bool = False) -> argparse.Argu if master_seed else "Check, correct, recover, and derive shares from codex32 backups." ), - epilog="Never include a secret or share in command arguments.\n" + epilog="Never put a secret or share in a command.\n" "Enter it when prompted. Some commands also accept piped input.", formatter_class=argparse.RawDescriptionHelpFormatter, allow_abbrev=False, diff --git a/tests/test_generic_hrp.py b/tests/test_generic_hrp.py index 0cf4f801..503be279 100644 --- a/tests/test_generic_hrp.py +++ b/tests/test_generic_hrp.py @@ -125,7 +125,7 @@ def test_cli_split_and_unknown_neutral_summary() -> None: " create create or confirm a backup, or split an existing secret\n" " wallet restore a Bitcoin Core wallet\n" " xprv export the root extended private key\n\n" - "Never include a secret or share in command arguments.\n" + "Never put a secret or share in a command.\n" "Enter it when prompted. Some commands also accept piped input.\n" ) for command in ("check", "correct", "secret", "share"):