AI App Security Scanner

ShipSafe

ShipSafe is the review step between 'the app runs' and 'the app is safe to deploy'. It scans AI-built codebases for leaked secrets, unsafe env usage, wildcard CORS, missing security headers, noisy production logs, and the auth-related issues that the free lite layer does not fully cover.

Secrets scanAuth reviewRLS audit

What it fixes

  • Hardcoded API keys, tokens, and passwords left in source code.
  • Missing .gitignore or .env.example hygiene before a repo gets pushed.
  • Server secrets leaking into the browser through dangerous NEXT_PUBLIC_* variables.
  • Wildcard CORS and missing security headers in shipping API routes.
  • Production console.log noise and select('*') overfetching left behind by AI tooling.
  • Auth and access-control bugs that do not show up in a simple secret scan.

What's inside

  • The free lite scanner pattern for hardcoded secrets, config hygiene, wildcard CORS, console logging, and select('*') checks.
  • A deeper paid review layer for auth logic, broken access control, and ownership verification.
  • getSession() vs getUser() detection for Supabase-auth patterns that look correct but are not safe server-side.
  • Supabase RLS policy analysis and SQL migration scanning.
  • API handler authorization review plus npm audit integration.
  • Auto-fix mode, baseline suppression, and a fuller category score breakdown.
  • Reference guides such as auth-review.md and a fix-playbook for remediation.

Before / After

Without rules

export const supabase = createClient(
  process.env.NEXT_PUBLIC_SUPABASE_URL!,
  process.env.NEXT_PUBLIC_SUPABASE_SERVICE_ROLE_KEY!
)

export async function GET() {
  return Response.json({ ok: true }, {
    headers: { "Access-Control-Allow-Origin": "*" }
  })
}

console.log(process.env.STRIPE_SECRET_KEY)

With rules

import "server-only"

export const supabase = createClient(
  process.env.NEXT_PUBLIC_SUPABASE_URL!,
  process.env.SUPABASE_SERVICE_ROLE_KEY!
)

const allowedOrigins = new Set(["https://0toprod.dev"])

export async function GET(request: Request) {
  const origin = request.headers.get("origin") ?? ""
  const response = Response.json({ ok: true })

  if (allowedOrigins.has(origin)) {
    response.headers.set("Access-Control-Allow-Origin", origin)
  }

  response.headers.set("X-Frame-Options", "DENY")
  return response
}

Free vs Full

The free repo is a useful first pass. The paid ShipSafe layer is where the more dangerous review work starts.

LayerFree GitHub ScannerFull ShipSafe
Hardcoded secret detectionIncludedIncluded
.env and .gitignore checksIncludedIncluded
NEXT_PUBLIC auditIncludedIncluded
CORS and security headersIncludedIncluded
console.log and select('*')IncludedIncluded
Auth logic reviewNot includedIncluded
getSession() vs getUser()Not includedIncluded
Supabase RLS policy analysisNot includedIncluded
SQL migration scanningNot includedIncluded
API handler authorization auditNot includedIncluded
Broken access control detectionNot includedIncluded
Ownership verificationNot includedIncluded
npm audit integrationNot includedIncluded
Auto-fix modeNot includedIncluded
Baseline suppressionNot includedIncluded
Score depthBasic scoreFull 3-layer score
Reference guidesNot includedIncluded

Compatibility

ShipSafe is positioned as both a standalone scanner and a skill layer for AI coding environments.

PlatformFormatStatus
Claude CodeSKILL.mdSupported
OpenAI Codex CLISKILL.mdSupported
Windsurfskills directoryPortable
Continue.devskills directoryPortable
Standalone CLIscripts/scan_repo.pySupported