This is a public-facing interactive tool that collects opt-in email addresses tied to a user's stack selection. The realistic threats are:
- Abuse of the email form — bots scripting fake submissions, spamming D1, or enumerating existing emails.
- Cross-site abuse — another site embedding the picker in an iframe, scraping the logos CDN traffic via referrer, or CSRF-posting to the subscribe endpoint.
- Supply chain — dependency vulnerabilities.
Input hardening (see src/server/index.ts)
Content-Type: application/jsonis required onPOST /api/subscribe.- Request body capped at 8 KiB (
Content-Length+ actual text length). - Email is validated against a regex and capped at 254 chars (RFC max).
- Stack object must have ≤ 32 keys and each value ≤ 64 chars.
User-Agentis truncated to 256 chars before being written to D1.- All queries use parameterized
prepare().bind()— no string concatenation.
- In-memory sliding-window rate limit: 5 requests / 60 s per IP, keyed
on
CF-Connecting-IP. This is per Worker isolate, so determined attackers can partially evade it across isolates — pair with a Cloudflare Rate Limiting rule for production.
- Origin enforcement: state-changing API requests (
POST /api/subscribe, etc.) are rejected server-side with403 Forbiddenwhen theOriginheader is missing or does not matchSITE_URL. CORS headers are layered on top for browser enforcement. Safe methods (GET/HEAD) are exempt so healthchecks and uptime monitors can probe/api/healthwithout an Origin. - Security headers on every response, including static HTML served from
the
ASSETSbinding — the Worker wraps every asset response (run_worker_first = true) so the picker's index.html carries CSP +X-Frame-Options+ friends, not just the API responses:X-Content-Type-Options: nosniffX-Frame-Options: DENYReferrer-Policy: strict-origin-when-cross-originPermissions-Policy: camera=(), microphone=(), geolocation=(), interest-cohort=()Content-Security-Policyon HTML responses — scripts/styles are'self'only; images allow the three logo CDNs;frame-ancestors 'none'; nounsafe-eval.
- No secrets required by the app itself.
wrangler.tomlcontains only non-sensitive identifiers (Worker name, D1 binding, database_id, SITE_URL). - If you add an admin endpoint later, use
wrangler secret put. .env,.env.local,.dev.vars, andconfig/site.tsare gitignored.
npm auditshows 0 vulnerabilities at the time of writing. Re-run before each deploy.
- Email verification — we accept any syntactically valid email. Add a double-opt-in flow if you plan to mail those addresses.
- Bot detection — for a higher-value form, front it with Cloudflare Turnstile.
- DDoS protection beyond Cloudflare's baseline — enable Cloudflare Bot Fight Mode and WAF rules if the picker starts attracting abuse.
- GDPR / CCPA compliance — this codebase doesn't include a cookie banner, consent management, or data-export/delete tooling. Add those before going live in regulated jurisdictions.
Open a private report via GitHub Security Advisories, or email the
address in the deploying instance's SITE.brand.href / repo profile.