Skip to main content

Security Sweep — qody.ba (MC #107297)

Security Sweep — qody.ba (MC #107297)

Date: 2026-08-18
Canonical repository: Azure DevOps QODY, GitHub private mirror
Production merge: 630f4cff5d7f1bfd6cf163e503223cbf23c4d671
Azure PR: #350 · CI build: #1120

Baseline

  • Repository already private; reachable history and working candidate had zero Gitleaks findings.
  • Live wrangler.toml returned its exact control-file content.
  • Unknown/sensitive paths returned the landing homepage with HTTP 200 because no 404 page existed.
  • Landing responses lacked CSP, HSTS, frame and permissions protection.
  • Root asset directory mixed runtime files with Wrangler config, Functions, TypeScript source and generated caches.
  • Contact Function threw on malformed JSON, had no OPTIONS/body/rate controls, logged name/venue/email/IP/country, and returned success without checking provider delivery.
  • apps/landing/ was excluded from repository Semgrep scans.

Remediation

  • Created physical runtime-only apps/landing/public/ root; Functions, config, source, tests and package metadata remain outside it.
  • Updated Wrangler output and DEPLOY-MAP to deploy only public/ after npm audit/preflight/type/tests.
  • Added true 404, CSP/HSTS/browser headers and defense-in-depth .assetsignore.
  • Hardened contact Function with streaming 8 KiB bound, strict JSON/field/email/phone validation, origin/method controls, honeypot, rate limit, no PII logs, provider timeout/status enforcement, generic failures and no-store/security headers.
  • Added honeypot consistently to HTML, TypeScript source and generated app.js; preflight asserts runtime/source consistency.
  • Added pinned test/type tooling and 7 contact-control tests; npm audit zero.
  • Added SHA-pinned GitHub mirror security CI and removed canonical landing from .semgrepignore.
  • Canonical Azure build policy #1120 passed; AzDO PR #350 merged without bypass and GitHub main mirror fast-forwarded.
  • Added exact Cloudflare edge tombstone for stale cached /wrangler.toml until cache expiry.

Verification

  • Local preflight/type/tests/audit: PASS; 7/7 tests.
  • Semgrep landing: 0 findings / 0 errors.
  • Gitleaks current/all reachable history: 0.
  • Local Wrangler smoke: runtime root 200; config/source/package/unknown paths 404; Function controls pass.
  • Independent review: PASS, P0=0, P1=0.
  • Cloudflare preview Playwright: 21/21 PASS, zero console errors.
  • Production Playwright: 21/21 PASS, zero console errors.
  • Production sensitive/control paths: 404 after edge routing.

Boundaries and residuals

  1. In-memory rate limiting is best-effort per Worker isolate; add Cloudflare Rate Limiting/Turnstile only under a separate abuse-volume decision.
  2. MailChannels remains a third-party delivery dependency; Function now fails honestly on non-2xx delivery.
  3. Existing payment webhook replay finding MC #106337 remains separate and was not duplicated or modified.
  4. Canonical dirty developer checkout was not reset or cleaned; remediation used an isolated worktree.

Evidence

/Users/makinja/system/evidence/107297/