Skip to content

Security: vietdhholatech/Dev

Security

docs/SECURITY.md

Security model

This document states what the tool protects against, what it does not, and where its guarantees stop. Read the last section before trusting it with funds.

Full design rationale: plans/bip39-offline-mnemonic-tool.md.

Status: functionally complete, not release-hardened. Generation, validation, the integrity guards and the process hardening below are all implemented and working. Verified by hand with strace: zero network syscalls, zero files opened for writing, getrandom as the only entropy source, RLIMIT_CORE set to zero.

Still missing: those checks running automatically on every commit, extended fuzzing, and a reproducible signed release. One-off evidence is weaker than a gate — for real funds, wait for a signed reproducible release, or audit and build it yourself.

What this tool is

A recovery phrase is the wallet. Anyone who reads it owns the funds, forever, with no revocation and no recourse. The entire design follows from that: the smallest possible amount of code, doing one job, with no way to reach the network and no path that writes a secret anywhere.

Assets

Asset Lifetime Notes
Raw entropy (16 or 32 bytes) milliseconds, during generation highest value; equals the wallet
Mnemonic sentence seconds to minutes, in memory and on screen equivalent to the entropy
Passphrase and derived seed test-gated seed feature only not exposed by the CLI in v1
Wordlist and binary integrity persistent corruption yields silently weak or unrestorable output

Threats addressed

Threat Mitigation
Exfiltration by the tool or a dependency no network-capable crate may enter the tree (deny.toml); builds and tests run in an unshared network namespace (ci/no-network.sh); syscall tracing
Tampered or substituted wordlist pinned SHA-256, compile-time embedding, structural unit tests, runtime self-check before every operation, cross-checked provenance
Weak or predictable entropy OS CSPRNG only; failure aborts rather than falling back; the deterministic test source cannot be compiled into a release binary
Malicious dependency four runtime dependencies, Cargo.lock with per-crate checksums, reviewed tree snapshot, cargo-deny advisories/licenses/bans/sources
Secrets written to disk or logs core crate performs no I/O and cannot log; no files, no environment access, no clipboard; RLIMIT_CORE=0; leak harness
Secrets on the command line mnemonics are never accepted via argv — process listings and shell history persist it
Secrets in a redirected file generate refuses a non-TTY stdout unless explicitly overridden
Clipboard managers and sync services no clipboard integration exists, and no flag adds one
Swap capturing secret pages best-effort mlock/VirtualLock, with a visible warning when unavailable

Threats not addressed

Stated plainly, because a security tool that implies more protection than it delivers is worse than one that admits its limits.

  • A compromised operating system. Malware with your privileges can read this process's memory or the screen. No generator can defend against this. If the machine might be compromised, the phrase it produces must be assumed known.
  • Hardware implants, EM emissions, acoustic and optical side channels.
  • Someone reading your screen, or a camera pointed at it.
  • Your own handling after the phrase leaves the screen: a photograph, a cloud note, or a password manager sync defeats everything above.

Where memory clearing cannot be guaranteed

Secrets are held in fixed-size buffers that are wiped on drop. That is a real mitigation, and it is not absolute. It does not reach:

  • Kernel and C library internals. Copies of RNG output and terminal buffers exist inside the kernel and libc. Userspace cannot reach them.
  • Terminal emulator memory and scrollback. Displaying a phrase discloses it to the terminal. The clear sequence erases scrollback only on emulators that honour it, and multiplexers or terminal logging may retain it regardless.
  • Swap and hibernation. Without mlock privilege, pages can reach swap. A hibernation image can capture even locked pages on some systems.
  • Compiler-managed copies. Moves can leave dead stack copies that wiping cannot chase. Fixed-size buffers and minimal moves reduce this; nothing eliminates it.
  • Browser and WASM builds (not built; see the plan, Phase 4). JavaScript strings are immutable and the garbage collector copies freely. Wiping is not possible there in any meaningful sense. A browser build is a convenience and validation tier, never the recommended way to generate a phrase for real funds.

Using this safely

  1. Run on a dedicated offline machine, or an amnesic live operating system.
  2. Verify the release signature and digest before running, then run selftest.
  3. Generate, transcribe to paper or steel, and verify the transcription.
  4. Power the machine off.
  5. Never photograph the phrase, type it into a connected device, or store it in a file, note-taking app or password manager.

What this tool will never do

No wallet recovery, partial-phrase or missing-word search, checksum repair, candidate enumeration or brute force. No balance lookup, blockchain access, address derivation or wallet scanning. No telemetry, analytics, crash reporting or update checks. See §15 of the plan for the full contract.

These are refused on request. The error messages are deliberately unhelpful for search: a failed checksum reports that it failed and nothing more.

The passphrase (optional, advanced)

BIP-39 allows an optional passphrase, sometimes called a "25th word", which changes the derived seed. It is documented here for completeness and is not exposed by the CLI in v1.

Two things must be understood before using one. If you forget it, the funds are gone — it cannot be recovered or reset. And it is not a substitute for secure entropy: a strong passphrase on a weakly generated mnemonic is still a weak wallet.

Reporting a vulnerability

Report privately to the repository owner. Do not open a public issue for a finding that affects generated phrases. Never include a real mnemonic, seed or private key in a report — reproduce with the public test vectors instead.

There aren't any published security advisories