Home/Sample reports/SECURITY-AUDIT.md

SECURITY-AUDIT.md

A real report, written by 06 · Security & Privacy Audit, run against this repo — dogfood output, committed unedited. This is the artifact every brief ends in: findings that cite their evidence, ranked by severity, with a fix sketch each.

Produced by brief 06 · Security & Privacy Audit, run against this repo (goal-prompts, v0.4). Part of the sample-report gallery.

Posture summary

Static site with no backend, no accounts, no stored user data beyond device-local preferences — the attack surface is client-side JavaScript, the supply chain, and the curl-pipe-to-shell installer pattern. Trust boundaries: the search box (only user input reaching the DOM) and everything downloaded by the installer.

Findings

1. Self-XSS at the search/empty-state boundary — was High-adjacent · FIXED in 0.4 Location: template.html empty-state rendering. Risk: user-typed query flowed into innerHTML; self-only today, reflected the day anyone adds a ?q= parameter. Fix shipped: textContent construction. Adopted default: user input never meets innerHTML anywhere in this codebase.

2. Installer had no integrity check — Medium · FIXED in 0.4 Location: install. Risk: curl-pipe-sh delivers whatever the CDN serves; users had no way to detect tampering or corruption. Fix shipped: build.py publishes checksums.txt (sha256 of both archives); the installer downloads to a temp file and verifies before extracting when sha256sum exists, hard-failing on mismatch.

3. No security headers — Medium · FIXED in 0.5 Location: vercel.json (absent headers block). Risk: no X-Content-Type-Options, Referrer-Policy, or frame-ancestors control; a strict CSP is complicated by the inline script and Google Fonts but a baseline is free. Fix: add nosniff, Referrer-Policy: strict-origin-when-cross-origin, and frame-ancestors 'self' via a headers block. Fix shipped: vercel.json now sends X-Content-Type-Options: nosniff, Referrer-Policy: strict-origin-when-cross-origin, and Content-Security-Policy: frame-ancestors 'self' on every route.

4. Runtime third-party dependency: Google Fonts — Low · FIXED in 0.8 Location: template.html head. Risk: availability and a request leak to a third party on every visit. Fix shipped: both families vendored as woff2 under fonts/ (OFL); no fonts.googleapis/gstatic requests remain in the built site (224243d). This also cleared the last blocker for the offline PWA.

5. MCP server trust scope — informational mcp/server.cjs reads only its own package files, takes no network or filesystem input beyond tool arguments, and executes nothing. The meaningful trust decision is npx github: itself — users execute this repo's code; the linter and CI keep the diff surface reviewable.

Fix-this-week

Finding 3 shipped in 0.5 (the headers block below). Finding 4 (self-hosting fonts) shipped in 0.8 — no open findings remain.

Defaults to adopt

User input renders via textContent only; anything piped to a shell ships a published checksum; new runtime third-party dependencies require a reason in the PR.

Report only — which fixes should be made?