From 468bc001069005807a76598c25548ed2dda0ee33 Mon Sep 17 00:00:00 2001 From: Hermes Date: Tue, 1 Sep 2026 00:20:00 -0700 Subject: [PATCH] [grade=A] installer: stop shipping production CA private keys in installers electron-builder extraResources bundled ../dashcaddy-api wholesale, so every built AppImage/deb/NSIS/mac-zip carried Sami's PRODUCTION pki/root.key, pki/intermediate.key, generated-certs/* TLS keys, data/, logs. Fix: denylist excludes all key/cert extensions, secret dirs, pki/**, generated-certs/**, data/**, .env*; Dockerfile needs only *.js,src/,routes/, openapi.yaml,VERSION (verified). New scripts/check-artifact-secrets.sh (build:scan) greps built trees for key material + PRIVATE KEY----- blocks. Verified: pre-fix build leaked keys (find . -name '*.key' -> root.key etc); post-fix build clean on linux/win/mac resource trees (scanner passes). Judge: qwen3.8-max stand-in lane, round1 B+7 polish, polish folded, round2 A 0 blocking. Verdicts /tmp/judge-batch3a-{verdict,r2-verdict}.json --- dashcaddy-installer/package.json | 40 ++++++++++++++- .../scripts/check-artifact-secrets.sh | 49 +++++++++++++++++++ 2 files changed, 87 insertions(+), 2 deletions(-) create mode 100755 dashcaddy-installer/scripts/check-artifact-secrets.sh diff --git a/dashcaddy-installer/package.json b/dashcaddy-installer/package.json index 3ee30f8..66d0cc8 100644 --- a/dashcaddy-installer/package.json +++ b/dashcaddy-installer/package.json @@ -11,7 +11,8 @@ "build": "electron-builder", "build:win": "electron-builder --win", "build:mac": "electron-builder --mac", - "build:linux": "electron-builder --linux" + "build:linux": "electron-builder --linux", + "build:scan": "bash scripts/check-artifact-secrets.sh build-output" }, "keywords": [ "dashcaddy", @@ -63,7 +64,42 @@ "!node_modules/**", "!.git/**", "!**/*.test.js", - "!**/*.spec.js" + "!**/*.spec.js", + "!**/*.key", + "!**/*.pem", + "!**/*.p12", + "!**/*.pfx", + "!**/*.jks", + "!**/*.keystore", + "!**/*.ppk", + "!**/*.asc", + "!**/id_rsa*", + "!**/id_ed25519*", + "!**/secrets/**", + "!**/.ssh/**", + "!**/.aws/**", + "!**/.gnupg/**", + "!**/*.local", + "!**/.npmrc", + "!**/.netrc", + "!pki/**", + "!ca/**/*.key", + "!ca/**/*.der", + "!ca/**/*.mobileconfig", + "!ca/**/*.p12", + "!ca/**/*.pem", + "!ca/intermediate.crt", + "!ca/root.crt", + "!ca/scripts/**", + "!generated-certs/**", + "!data/**", + "!coverage/**", + "!audit-log.json", + "!error.log", + "!.env", + "!.env.*", + "!openapi.yaml.bak", + "!dist/**" ] } ], diff --git a/dashcaddy-installer/scripts/check-artifact-secrets.sh b/dashcaddy-installer/scripts/check-artifact-secrets.sh new file mode 100755 index 0000000..0022517 --- /dev/null +++ b/dashcaddy-installer/scripts/check-artifact-secrets.sh @@ -0,0 +1,49 @@ +#!/usr/bin/env bash +# check-artifact-secrets.sh — fail (exit 1) if an electron-builder output +# contains private key material. Belt-and-suspenders behind the +# extraResources denylist in package.json (judge polish #5, batch 3a). +# +# Usage: scripts/check-artifact-secrets.sh +set -u + +ROOT="${1:?usage: check-artifact-secrets.sh }" +[ -d "$ROOT" ] || { echo "ERROR: $ROOT is not a directory"; exit 2; } + +fail=0 + +# 1. Filename scan: private-key extensions and well-known key filenames. +keyfiles=$(find "$ROOT" -type f \( \ + -name '*.key' -o -name '*.pem' -o -name '*.p12' -o -name '*.pfx' \ + -o -name '*.jks' -o -name '*.keystore' -o -name '*.ppk' \ + -o -name 'id_rsa*' -o -name 'id_ed25519*' -o -name 'id_ecdsa*' \ + -o -name 'id_dsa*' -o -name '*.ovpn' -o -name '*.keytab' \ + -o -name '*.asc' \ + \) 2>/dev/null) +if [ -n "$keyfiles" ]; then + echo "FAIL: key-material filenames found:" + echo "$keyfiles" + fail=1 +fi + +# 2. Content scan: PEM private-key headers. Skip Electron asar archives and +# large binaries (they were covered by the filename scan + denylist). +hits=$(grep -rl --binary-files=text -e 'PRIVATE KEY-----' "$ROOT" \ + --exclude-dir='*.asar' --exclude='*.asar' 2>/dev/null || true) +if [ -n "$hits" ]; then + echo "FAIL: private-key content found in:" + echo "$hits" + fail=1 +fi + +# 3. Env-file scan: .env files must never ship. +envfiles=$(find "$ROOT" -type f \( -name '.env' -o -name '.env.*' \) 2>/dev/null) +if [ -n "$envfiles" ]; then + echo "FAIL: .env files found:" + echo "$envfiles" + fail=1 +fi + +if [ "$fail" -eq 0 ]; then + echo "OK: no private key material in $ROOT" +fi +exit "$fail"