buildsafely
Security scanner for AI-coded apps.
Finds the bugs Claude, Cursor, and Lovable get wrong.
Example scan — this is what buildsafely produces
https://demo-shop.example.com
- HIGHURL-04conf HIGHSession cookie `sb-access-token` missing: Secure, HttpOnly, SameSite=Lax or StrictCookie `sb-access-token` looks like a session/auth cookie but lacks required security flags (Secure, HttpOnly, SameSite=Lax or Strict).
- cookie_name
- sb-access-token
- missing_flags
- ["Secure","HttpOnly","SameSite=Lax or Strict"]
- raw_set_cookie
- sb-access-token=eyJhbGciOi…; Path=/
Remediation prompt ▸
Review before pasting into a terminal.SECURITY FIX (HIGH): The session cookie `sb-access-token` is missing the following security flags: Secure, HttpOnly, SameSite=Lax or Strict. Risk: - Missing HttpOnly: attacker who finds an XSS vulnerability can steal this cookie via document.cookie. - Missing Secure: cookie sent over HTTP can be intercepted. - Missing SameSite: cookie can be sent in cross-site requests, enabling CSRF. Please: 1. Locate where you set this cookie. If using Supabase auth, this is handled by the @supabase/ssr library — check that you're using the latest version and using createServerClient correctly. 2. For Next.js cookies set manually: cookies().set('sb-access-token', value, { httpOnly: true, secure: true, sameSite: 'lax', path: '/', maxAge: 60 * 60 * 24 * 7 // 1 week }); 3. For session libraries (iron-session, next-auth, etc.), confirm the cookie config includes all three flags. Verification: curl -sI 'https://demo-shop.example.com' | grep Set-Cookie — every session/auth cookie must have HttpOnly, Secure, SameSite. - MEDIUMURL-03conf HIGHMissing security header: Content-Security-PolicyControls which resources can be loaded; primary XSS mitigation.
- missing_header
- Content-Security-Policy
- url
- https://demo-shop.example.com
Remediation prompt ▸
Review before pasting into a terminal.SECURITY FIX (MEDIUM): The deployed site is missing the following security header: Content-Security-Policy. Missing on: https://demo-shop.example.com Add it. For Next.js, in next.config.js: async headers() { return [{ source: '/:path*', headers: [ { key: 'Strict-Transport-Security', value: 'max-age=63072000; includeSubDomains; preload' }, { key: 'X-Content-Type-Options', value: 'nosniff' }, { key: 'X-Frame-Options', value: 'DENY' }, { key: 'Referrer-Policy', value: 'strict-origin-when-cross-origin' }, { key: 'Content-Security-Policy', value: "default-src 'self'; frame-ancestors 'none';" } ] }]; } For Vercel: same headers in vercel.json. For Cloudflare Workers / other: add at the edge. Verification: curl -sI 'https://demo-shop.example.com' | grep -i 'Content-Security-Policy' — must be present. - LOWURL-09conf HIGHFramework version disclosed in headersResponse headers disclose framework/version info: X-Powered-By: Express, Server: nginx/1.18.0
- headers
- {"X-Powered-By":"Express","Server":"nginx/1.18.0"}
Remediation prompt ▸
Review before pasting into a terminal.SECURITY FIX (LOW): Response headers disclose your framework and version: X-Powered-By: Express, Server: nginx/1.18.0. This is defense-in-depth — not directly exploitable, but helps attackers know which CVEs to try. Please: 1. For Next.js, set in next.config.js: `const nextConfig = { poweredByHeader: false };` 2. For Express: `app.disable('x-powered-by');` 3. For nginx / Apache: `server_tokens off;` / `ServerTokens Prod` + `ServerSignature Off`. Verification: curl -sI 'https://demo-shop.example.com' must not contain X-Powered-By or version-numbered Server header.
Detects things like:
- Supabase tables shipped without Row-Level Security
- Stripe webhook handlers that skip signature verification
- Service-role API keys leaked into client JS bundles
- Server Actions missing auth checks
- …14 more antipatterns in the MVP rule set