Skip to content

security: fix 3 open-source blockers (docs + timing attack) - #126

Merged
Flotapponnier merged 1 commit into
mainfrom
security/blockers-pre-opensource
May 23, 2026
Merged

security: fix 3 open-source blockers (docs + timing attack)#126
Flotapponnier merged 1 commit into
mainfrom
security/blockers-pre-opensource

Conversation

@Flotapponnier

Copy link
Copy Markdown
Collaborator

Avant d'open-source : 3 fixes critiques.

  1. Internal docs removed — 5 fichiers (deployment-checklist, tiered-architecture, cost-model, active-bench-plan, france-cryptos-roadmap) sortis du repo. .gitignore inclut tripwire patterns pour empêcher re-introduction.
    ⚠️ Git history contient encore ces fichiers. Avant de flip public : git filter-repo --invert-paths --path docs/solana-landing-... + force-push vers mirror public.
  2. CRON_SECRET timing-safecrypto.timingSafeEqual() au lieu de ===. Pad provided header pour éviter throw sur length mismatch.
  3. Fail-closed en prod — si CRON_SECRET tombe de l'env, prod refuse 401 (avant : silently autorisait).

.vercel/project.json était un faux positif de l'audit (jamais commité).

1) Internal docs moved out of the repo
   Five docs that leaked API key names, partner contracts, Railway
   service names, deployment budgets and 6-12 month business roadmap
   removed from HEAD and saved to a private location outside the repo:

     - docs/solana-landing-deployment-checklist.md
     - docs/solana-landing-tiered-architecture.md
     - docs/solana-landing-cost-model.md
     - docs/solana-landing-active-bench-plan.md
     - docs/france-cryptos-roadmap.md

   .gitignore picks up both the legacy filenames and a tripwire
   pattern (*-checklist / *-cost-model / *-roadmap / *-internal in
   docs/) so a future contributor can't reintroduce the same shape
   of internal-only doc without an explicit override.

   NOTE: git history still contains these files. Before flipping the
   repo public, run a one-off rewrite (git filter-repo --invert-paths
   --path docs/solana-landing-... etc) and force-push to a fresh
   public mirror. Not done here because it requires force-push
   coordination + a backup.

2) Constant-time CRON_SECRET comparison
   /api/cron/health-check now compares the Authorization header with
   crypto.timingSafeEqual instead of .
   The prior `===` shortcut leaked the secret one byte at a time
   under a remote timing attack (response latency varied with prefix
   match length). Pads provided header to expected length first to
   avoid throwing on mismatched buffer sizes, then ANDs with a
   length check so a shorter-but-prefix-matching header still fails.

3) Fail-closed in production when secret missing
   The previous `if (!secret) return true; // dev mode` would have
   silently published the route if CRON_SECRET fell off the vercel
   env (typo, rotation gap, project rename). Now production refuses
   any unsignaled request; dev keeps the permissive fallback.

.vercel/project.json was flagged in the audit as committed - confirmed
NOT committed (already in .gitignore). False positive, no action.
@Flotapponnier
Flotapponnier merged commit 93ec872 into main May 23, 2026
@Flotapponnier
Flotapponnier deleted the security/blockers-pre-opensource branch May 23, 2026 18:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant