harden: keep the test recovery phrase out of release bundles, match committed keys by content (closes #351)
The 12-word BIP-39 test phrase survived in every release bundle as dead text: module.exports keeps DEBUG_MNEMONIC live even though wallet.js's only use of it folds away in a release build, so it could not be tree-shaken. Putting the value itself behind the __BUILD_DEBUG__ define makes esbuild fold it to null, so no distributed bundle carries it. script/verify-build now fails a release build if the phrase appears in any emitted file, so the fold cannot silently regress; test-verify-build covers both the release failure and the debug allowance. tests/extensionId.test.js now scans the content of every tracked file for a PEM private-key header instead of matching filename extensions alone, so a key committed under an unexpected name is caught. Model: opus-4-8
This commit was merged in pull request #397.
This commit is contained in:
@@ -89,19 +89,28 @@ describe("chrome extension identity", () => {
|
||||
|
||||
// The private half is a credential. It has never been in this repo and no
|
||||
// target generates one into the working tree; this fails loudly if that
|
||||
// ever changes, because a committed .pem is a key anyone can sign a CRX
|
||||
// with under this extension's id.
|
||||
// ever changes, because a committed private key is one anyone can sign a
|
||||
// CRX with under this extension's id.
|
||||
//
|
||||
// Matched by CONTENT, not by filename: a key committed as notes.txt or with
|
||||
// no extension carries the same risk as one named key.pem, and a
|
||||
// filename-only check waves it through. The PEM header a private key opens
|
||||
// with is the signature searched for. The pattern does not trip on its own
|
||||
// source: the bracket-expression characters between the two anchors are not
|
||||
// in the character class, so this file is not a match for it.
|
||||
const PRIVATE_KEY_HEADER = /-----BEGIN [A-Z0-9 ]*PRIVATE KEY-----/;
|
||||
test("no private key is committed anywhere in the tree", () => {
|
||||
const root = path.join(__dirname, "..");
|
||||
const tracked = require("child_process")
|
||||
.execSync("git ls-files", {
|
||||
cwd: path.join(__dirname, ".."),
|
||||
encoding: "utf8",
|
||||
})
|
||||
.execSync("git ls-files", { cwd: root, encoding: "utf8" })
|
||||
.split("\n")
|
||||
.filter(Boolean);
|
||||
expect(tracked.filter((f) => /\.(pem|key|p12|pfx)$/i.test(f))).toEqual(
|
||||
[],
|
||||
const offenders = tracked.filter((f) =>
|
||||
PRIVATE_KEY_HEADER.test(
|
||||
fs.readFileSync(path.join(root, f), "latin1"),
|
||||
),
|
||||
);
|
||||
expect(offenders).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user