Security Sweep — bilko.io RS — MC #107299 (2026-08-18)
bilko.io Security Sweep — MC #107299
Verdict: PASS
Date: 2026-08-18
Scope: bilko.io RS landing only (apps/landing-io); separate from bilko.cloud and bilko.company.
Confirmed baseline findings
- P1 — source/config exposure: mixed Pages root served exact
wrangler.toml,package.json,pnpm-lock.yamlandapp/page.tsx(15,989 bytes) with HTTP 200. - P1 — no fail-closed cache boundary: removed assets could remain reachable through Pages cache; HR incident #107298 established one-week
s-maxagepersistence. - P2 — false 200: unknown and sensitive paths returned homepage HTTP 200.
- P2 — missing browser controls: no CSP, HSTS, frame denial or Permissions-Policy.
- P2 — lead endpoint hardening: unbounded bodies/fields and Turnstile success accepted without hostname validation or timeout.
- P2 — SAST blind spot:
apps/landing-io/was blanket-excluded from Semgrep.
Remediation
- Moved nine byte-identical runtime assets under physical
apps/landing-io/public/; Next source/config/lockfile remain outside deploy root. - Added
.assetsignore, asset preflight, real404.html, CSP/HSTS/frame/referrer/permissions/COOP/CORP headers. - Added Pages middleware that returns 404/no-store for source, config, hidden and backup paths before asset-cache lookup.
- Wrangler/workflow/docs now deploy
publicfrom app cwd so sibling Functions compile. - Bounded bodies at 16 KiB and lead fields; unsupported media returns 415; arrays/non-objects fail closed.
- Turnstile now requires a secret, 5-second timeout, successful HTTP response and hostname
bilko.io. - Added ten IO security tests; canonical landing suite updated to Fetch-compatible Requests/public HTML path.
- Removed blanket Semgrep exclusion; escaped JSX URL entities to obtain complete parsing without changing rendered URLs.
Verification
- IO security tests: 10/10 PASS.
- Canonical landing suite: 29/29 PASS.
- Configured landing Gitleaks: 0; Semgrep: 0 findings / 0 parse errors; pnpm audit: 0 all severities.
- Local Wrangler: Worker compiled; runtime pages 200; source/config/unknown paths 404; Function invalid/OPTIONS guards pass.
- Preview Playwright: 5/5 PASS, desktop/mobile screenshots; no real lead submitted.
- AzDO PR #354, build #1134 PASS, merge
771e9c6d078945ec23319a83d3e7ff275aa8cedd. - Production deployment
6bb2f936-b640-4653-b62b-645d914c056d, source771e9c6. - Production Playwright: 5/5 PASS.
- Final exact probes: 18/18 sensitive/source/config paths HTTP 404; guarded paths
Cache-Control: no-store. - Homepage bytes/hash exactly match merged
public/index.html; TLS and browser headers verified live. - Task preview deleted; no #107299 preview remains.
Linked finding reconciliation
- #106358: production and preview binding policy remains explicit in
wrangler.toml; both deployments loggedCompiled Worker. Preview deliberately has no production KV binding. - #106405: current live Turnstile sitekey
0x4AAAAAADAlOJsyIecNG_GGremains pinned; deleted widgets are rejected by canonical tests. The approved removal of invaliddata-size="invisible"is now live. - No real lead, Slack message or KV record was created during this sweep.
Residual constraints
- CSP retains
'unsafe-inline'because canonical static HTML embeds inline script/style; future hash/nonce migration is recommended. - Valid Turnstile/real-lead submission was intentionally not executed. Evidence covers current sitekey, DOM source, invalid/hostile paths, unit contracts, compiled Worker and binding config.
- Shared monorepo raw Gitleaks history reports documented synthetic test values/placeholders; configured landing scan is zero. This PASS does not apply to bilko.company or authenticated Bilko SaaS.
Evidence anchors
final-live-security-summary.jsonproduction-playwright-report.jsonazdo-build-1134.jsonazdo-pr-completed.jsonremediation-local/screenshots/production-final-desktop.pngscreenshots/production-final-mobile.png
No comments to display
No comments to display