security: make DEBUG a build-time flag defaulting to off (closes #149)
All checks were successful
check / check (push) Successful in 29s
All checks were successful
check / check (push) Successful in 29s
DEBUG was hardcoded to true in src/shared/constants.js, so every wallet created from a build of main received the publicly committed test recovery phrase and was instantly drainable. There was no way to produce a non-debug build at all: the real entropy path in generateMnemonic() was dead code in every artifact. DEBUG is now a build-time constant injected by esbuild's define in build.js, alongside the existing __BUILD_* defines, and read by constants.js with the same typeof guard buildInfo.js uses. It is false unless the build was run with AUTISTMASK_DEBUG=1 — an exact match, so an unset, empty or mistyped value fails safe towards a release build. The build prints which mode it used, and make build-debug is a shim for the debug case. What DEBUG does when enabled is unchanged: the red banner plus the hardcoded test phrase, no new conditionals. Mnemonic generation deliberately keeps reading the compile-time constant rather than isDebug() from log.js, which also ORs in the runtime debugMode flag the settings toggle drives; routing it through isDebug() would let a user of a release build re-enable the known test phrase for real wallets. That is now recorded at the call site, in the README DEBUG Mode Policy, and covered by a regression test. New tests/wallet.test.js covers both build modes: with the flag off, two successive generateMnemonic() calls differ, both validate as BIP-39 phrases, both are 12 words, neither is DEBUG_MNEMONIC, and the result still derives a usable HD wallet — including with the runtime toggle forced on. With the flag on, DEBUG is true and the test phrase is returned, so the debug path stays proven rather than silently removed. Verified with make check (55 tests, lint, fmt-check all green), and with make build and make build-debug: all four bundles across dist/chrome and dist/firefox export DEBUG:!1 in a release build and DEBUG:!0 in a debug build, and AUTISTMASK_DEBUG=true likewise yields DEBUG:!1.
This commit is contained in:
30
README.md
30
README.md
@@ -42,6 +42,23 @@ Load the extension:
|
||||
- **Firefox**: Navigate to `about:debugging#/runtime/this-firefox`, click "Load
|
||||
Temporary Add-on", and select `dist/firefox/manifest.json`.
|
||||
|
||||
### Debug Builds
|
||||
|
||||
`make build` always produces a release build: the build-time `DEBUG` constant is
|
||||
`false`, so wallet creation uses real entropy and the red banner is off. To
|
||||
produce a debug build instead, set `AUTISTMASK_DEBUG=1` in the environment:
|
||||
|
||||
```bash
|
||||
make build-debug # or: AUTISTMASK_DEBUG=1 make build
|
||||
```
|
||||
|
||||
Only the exact value `1` enables it; any other value (including unset, empty, or
|
||||
`true`) yields a release build, so a typo cannot accidentally ship the debug
|
||||
behavior. The build prints which mode it used. See the
|
||||
[DEBUG Mode Policy](#debug-mode-policy) for what the flag changes. **Never
|
||||
distribute a debug build** — every wallet it creates gets the same publicly
|
||||
known test recovery phrase.
|
||||
|
||||
## Entrypoints
|
||||
|
||||
This repository adheres to the
|
||||
@@ -668,6 +685,19 @@ flows, or alter program behavior beyond the banner and the hardcoded mnemonic.
|
||||
Adding new DEBUG-conditional branches requires explicit approval from the
|
||||
project owner.
|
||||
|
||||
`DEBUG` is a build-time constant, not a runtime setting. `build.js` injects it
|
||||
into the bundle as the `__BUILD_DEBUG__` define — `false` unless the build was
|
||||
run with `AUTISTMASK_DEBUG=1` (see [Debug Builds](#debug-builds)) — and
|
||||
`src/shared/constants.js` reads it. It cannot be changed after the bundle is
|
||||
produced.
|
||||
|
||||
The debug-mode toggle in settings is a separate, runtime-only flag. It raises
|
||||
the log level and turns the banner on, and that is all it may ever do: it feeds
|
||||
`isDebug()` in `src/shared/log.js`, which is deliberately not what
|
||||
`generateMnemonic()` consults. Mnemonic generation reads the build-time `DEBUG`
|
||||
constant directly, so no runtime toggle in a release build can reach the
|
||||
hardcoded test phrase.
|
||||
|
||||
### Key Decisions
|
||||
|
||||
- **No framework**: The popup UI is vanilla JS and HTML. The extension is small
|
||||
|
||||
Reference in New Issue
Block a user