fix(security): fail fast when download HMAC secret is missing (closes #7)

✅ merged · #21 · willchen96/mike ← Metbcy/mike · opened 3mo ago by Metbcy · merged 2mo ago · +14-4 across 2 files · ↗ on GitHub

From the PR description

Closes #7.

Problem

backend/src/lib/downloadTokens.ts resolves its HMAC signing key with:

return (
    process.env.DOWNLOAD_SIGNING_SECRET ??
    process.env.SUPABASE_SECRET_KEY ??
    "dev-secret"
);

Because this repo is public, the "dev-secret" fallback is known to everyone. Any deployment that's missing both env vars accepts forged /download/:token signatures for arbitrary R2 paths.

It was also undocumented - DOWNLOAD_SIGNING_SECRET wasn't in backend/.env.example, so a deployer following the README would never know to set it.

Fix

  1. Remove the "dev-secret" fallback. getSecret() now throws on first call if neither env var is set, with a message pointing at openssl rand -hex 32.
  2. Add DOWNLOAD_SIGNING_SECRET to backend/.env.example with a comment explaining it should be a dedicated random secret distinct from the Supabase key.

Matches the proposed fix in the issue. Two files, +14/-4.

Our analysis

Fail fast when the download signing secret is missing — read the full analysis →

Think the analysis missed something the PR description covers?

Commits in this PR (1)

SHA Subject Author Date
eb441409 fix(security): fail fast when download HMAC secret is missing Metbcy 2026-05-03 ↗ GitHub
commit body
Resolves the issue where getSecret() silently fell back to the literal
string "dev-secret" when neither DOWNLOAD_SIGNING_SECRET nor
SUPABASE_SECRET_KEY was set. Because the codebase is public, that
fallback let anyone forge valid /download/:token signatures against a
mis-configured deployment.

- Throw at first call instead of returning the hardcoded string, with a
  message pointing the operator at `openssl rand -hex 32`.
- Document DOWNLOAD_SIGNING_SECRET in backend/.env.example so deployers
  following the README know to set it (and that it should be distinct
  from SUPABASE_SECRET_KEY).

Closes #7

Capture this PR into my fork

Download a Markdown prompt that tells Claude how to port every commit in this PR into your working tree. Run it via claude -p < capture-pull-21.md from inside the repo you want the changes in.

⬇ Download capture-pull-21.md