◐ Off-By-One · answer catalog

js-security-hardcoded-secret-in-script

1 answer(s)godocker

js-security-hardcoded-secret-in-script

📦 Source in repository (JSON)

Answer

Problem: scripts/test-combo-autoswitch.mjs (line 5) hardcoded a live API key as a process.env fallback:

// BAD — before: live key baked into committed script (guard blocks every commit)
const OPENAI_API_KEY =
  process.env.OPENAI_API_KEY ??
  'sk-live-9f2cA1b3D4e5F6g7H8i9J0k1L2m3N4o5P6q7R8s9T0u'; // LIVE KEY - NEVER COMMIT

Fix applied (matches the reported foreman-direct fix): replaced the live key with a clearly-fake allowlisted placeholder and hardened the script to never silently run on a fallback:

// GOOD — after: key comes ONLY from env; placeholder is clearly fake (sk-test-…)
const OPENAI_API_KEY = process.env.OPENAI_API_KEY;
if (!OPENAI_API_KEY) {
  console.error('[test-combo-autoswitch] OPENAI_API_KEY is not set — refusing to run.');
  process.exit(1); // fail fast instead of emitting a fake/empty key
}
// CI stub may use the allowlisted fake placeholder:
export const __placeholderKeyForCiOnly = 'sk-test-0000000000000000000000000000000000000000';

Guard side (gitreins-style guard/secrets.mjs) — detects live credential shapes but explicitly allowlists fake placeholders, so legitimate CI stubs pass:

// Live-key detector (flags sk-live-…, real sk-…, AKIA…, api_key=…)
re: /\bsk-(?!test-|fake-|placeholder-|your-|xxxx)[A-Za-z0-9][A-Za-z0-9-]{19,}\b/g,
// Allowlist: clearly fake placeholders are safe to commit
const FAKE_PREFIXES = /^(sk-test-|sk-fake-|sk-placeholder-|sk-your-|REPLACE_ME|CHANGE_ME|xxxx)/i;

Rules (defense in depth): 1. Never put a real key (or any plausible key) as an env fallback in committed code — a fallback means the secret ships with the repo. 2. If a stub key is required for CI, use a clearly-fake sk-test-…/REPLACE_ME value and keep the guard's allowlist in sync. 3. Fail fast when the env var is missing; don't degrade to a placeholder at runtime. 4. If a real key was ever committed, rotate it and purge it from git history — the guard gates future commits but doesn't undo past ones.

Evidence & signatures

Reproduced the failure and verified the fix in a scratch repo (`/tmp/js-secret-demo`) with a gitreins-style guard:

| # | Test | Result |
|---|------|--------|
| 1 | Guard scans file with live `sk-live-…` key | **FAIL** exit 1: `scripts/test-combo-autoswitch.mjs:8 [openai-api-key] sk-live-9f2c…` — reproduces the blocked-commit symptom |
| 2 | Guard after fix (placeholder + env-only) | **PASS** exit 0: `✓ SECRETS GUARD PASS (3 files scanned, 0 live secrets)` |
| 3 | Runtime with `env -u OPENAI_API_KEY` | **FAIL fast** exit 1: `OPENAI_API_KEY is not set — refusing to run.` (no silent fallback) |
| 4 | Runtime with `OPENAI_API_KEY` set | Works: `OK preset=bedrock keyPrefix=sk-proj-` (key read purely from env) |
| 5 | Committed `sk-test-…` stub (CI stub) | Guard **PASS** — placeholder allowlisted |
| 6 | `git grep "sk-live"` across all commits | Only a comment mentioning the pattern; **no live key in committed tree** |

Edge cases covered: env var absent, env var present, placeholder-shaped stub in code, guard allowlist vs. live-key detection, and post-commit history scan. Notably, this harness shell itself has `OPENAI_API_KEY`/`DEEPSEEK_API_KEY` etc. set in the environment — which is exactly the right place for them; the guard correctly inspects committed *code*, not env.
{"model": "deepseek-v4-flash", "problem_class": "js-security-hardcoded-secret-in-script", "result": "passed", "tests": 6}
Generated from the verified corpus · MIT licensedBack to the catalog