FixVibe

// docs / security guides / pre-ship checklist

Vibe coding 安全检查清单:上线前 51 项

针对使用 Cursor、Claude Code、Lovable、Bolt、v0、Replit 和 Windsurf 构建的应用程序的实用的、分阶段组织的清单。每个项目都可以在五分钟内完成。在投入生产之前运行它,然后在每个主要版本之前再次运行它。项目分为七个类别——秘密、数据库、身份验证、标头、第三方、部署、监控——并标记有它们适用的部署阶段。

PRE = pre-deploy (audit your source). DEPLOY = at deploy time. POST = post-deploy verification.

秘密和API密钥(8项)

硬编码按键是振动编码应用程序中最常见的一个现象。八项措施可将其拒之门外:

  1. PRE — Audit NEXT_PUBLIC_ env vars. 任何以 NEXT_PUBLIC_ 为前缀的内容都包含在客户端捆绑包中。如果其中一个是 Supabase service_role 密钥(解码为 JWT 和 "role":"service_role"),请将其删除并通过仅服务器客户端(src/lib/supabase/service.ts 和 import 'server-only')进行路由。
  2. PRE — Grep for hardcoded provider keys. 搜索 sk_live_、pk_live_、STRIPE_SECRET、sk-ant-、sk-、AIza、AKIA 和 JWT- 查找字符串 (eyJ) 的源。将每个命中移至 .env.local 并仅通过 process.env.* 服务器端进行引用。
  3. PRE — Verify .gitignore. 确认.env*.local、.npmrc、.yarnrc,并且任何特定于提供商的凭据文件都将被忽略。通过您的提供者模式运行 git ls-files 以查找已提交的任何内容。
  4. PRE — Scan the built bundle. 运行 npm run build,然后 grep .next/static 和相同模式的任何 dist/ 输出。如果密钥到达捆绑包,则开发人员永远不会进行干净的环境分离。
  5. DEPLOY — Set secrets per environment. Vercel:设置→环境变量,每个变量的范围为Pro归纳/预览/开发。切勿与预览环境共享sk_live_*。使用Vercel 的加密环境变量存储,而不是内联工作流程机密。
  6. DEPLOY — Disable build-log secret echo. 构建期间的一些 CI 配置 echo 环境变量。审核您的vercel.json、GitHub 操作工作流程或Cloudflare 页面设置,以查找任何会将值推送到公共构建日志中的echo $SECRET。
  7. POST — Run a passive scan. FixVibe 的Free 层涵盖了这一点:粘贴部署的URL,等待约20 秒,查找secrets.* 结果。 Secrets in JavaScript Bundles 检查捕获通过误用SDK 而落在localStorage 或sessionStorage 中的键。
  8. POST — Rotate any key that ever shipped. 如果密钥在公共捆绑包中存在甚至几分钟,则将其视为已泄露。通过仪表板轮换 Supabase 服务角色密钥,重新生成 Stripe 受限密钥,通过控制台撤销 Anthropic / OpenAI / Google 密钥。

数据库访问控制:RLS和Firestore规则(6项)

BaaS 默认值是有意允许的,因此第一个教程有效。 Pro归纳需要明确的政策。

  1. PRE — Enable RLS on every public.* table. In Supabase: each table needs ALTER TABLE ... ENABLE ROW LEVEL SECURITY plus explicit policies for each role. RLS is what stops the anon and authenticated API roles; FORCE ROW LEVEL SECURITY only extends it to the table owner and is optional defence in depth.
  2. PRE — Write a policy per (table, role, action). 最小值:加入auth.uid() 的SELECT 策略。更好:单独的INSERT / UPDATE / DELETE 策略,这样UPDATE 就无法偷偷引入user_id 重新路由所有权的更改。
  3. PRE — Replace default Firebase rules. 默认测试模式规则为allow read, write: if true;。替换为每个集合的身份验证绑定规则:match /users/{userId} 与 allow read, write: if request.auth.uid == userId;
  4. PRE — Lint migrations in CI. 在合并之前运行 supabase db lint 或等效命令。如果任何CREATE TABLE public.* 缺少匹配的RLS 策略,CI 应该使构建失败。
  5. DEPLOY — Confirm RLS survived deploy. 部署后重新检查Supabase Studio:表 → 每行 → RLS 切换为 ON。 Pro归纳数据库迁移有时会领先于策略文件;验证该政策是否有效。
  6. POST — Run an active scan against a verified domain. Supabase Row-Level Security 主动检查使用匿名键写入一个微小的种子行,并报告写入是否成功 - i.e。 RLS实际上并没有强制执行。

身份验证和会话(7 项)

AI-编码应用程序中的身份验证错误往往很微妙:令牌验证中的一对一偏差、丢失HttpOnly标志、getSession()(本应有getUser())。

  1. PRE — Replace getSession() with getUser(). getSession() 读取cookie并信任它; getUser() 与Supabase 后端进行验证。在服务器路由上始终使用getUser()。
  2. PRE — Confirm token expiry. Magic-link、密码重置和电子邮件验证令牌需要服务器强制过期。默认Supabase 魔法链接会在 1 小时后过期——如果没有真正的原因,请勿将其覆盖为更高的数字。
  3. PRE — Verify JWT aud and exp. 如果您在任何地方手动解码令牌,请检查这两个声明。更好:使用 SDK 的 getUser() 来为你做这件事。
  4. PRE — Audit cookie flags. 自定义会话 cookie 应为Secure; HttpOnly; SameSite=Lax(或Strict 对于非OAuth 流)。 localStorage 中没有课程材料。
  5. PRE — Validate the next redirect param. 登录后的next 查询参数必须以/ 开头,而不是//(打开重定向到attacker.example)。拒绝服务器端的任何其他内容。
  6. POST — Test logout. 登录、注销、检查 cookie(DevTools → 应用程序 → Cookies)。必须在同一响应中清除会话 cookie。如果它持续存在,则注销处理程序实际上并未破坏服务器端状态。
  7. POST — Active probe. Auth Flow Defects 和 Account Enumeration 检查表面破坏的身份验证边界 - 对“用户存在”与“错误密码”的不同响应、缺少登录速率限制、未签名的重置令牌。

HTTP 安全标头和内容安全策略(6 项)

标头是整个管道中最便宜的强化,也是代码生成器最常跳过的。

  1. PRE — Ship a real CSP. 最小值:script-src 'nonce-{NONCE}' 'strict-dynamic'; object-src 'none'; base-uri 'self'; frame-ancestors 'none'。 script-src 中没有'unsafe-inline'。当中间件设置 x-nonce 请求标头时,Next.js 自动应用随机数。
  2. PRE — Add the legacy three. X-Content-Type-Options: nosniff、X-Frame-Options: DENY(或单独依赖CSP frame-ancestors)、Strict-Transport-Security: max-age=31536000; includeSubDomains。
  3. PRE — Tighten Referrer-Policy. 默认strict-origin-when-cross-origin 适用于大多数应用程序。不要发送 unsafe-url 或根本不发送标头。
  4. PRE — Replace Access-Control-Allow-Origin: *. Grep 查找它。替换为明确的来源允许列表。无论* 与credentials: include 在一起,浏览器都会拒绝该请求——但这并不能防止后端配置错误。
  5. DEPLOY — Verify headers post-deploy. 打开 DevTools → 网络 → 单击根文档 → Headers 选项卡。 CSP、HSTS、X-Frame-Options、X-Content-Type-Options 应存在。 CSP 不得在script-src 中包含'unsafe-inline'。
  6. POST — Run HTTP Security Headers. 被动标头检查通过部署平台修复指南报告每个丢失的标头(Vercel vercel.json、Cloudflare 页_headers、Netlify _headers、Next.js 中间件)。

第三方集成和APIs(5 项)

您包含的每个脚本都是CSP 豁免和潜在的供应链表面。将第三方视为您信任边界的一部分。

  1. PRE — Reverse-proxy analytics where possible. PostHog、Plausible、Umami 都支持通过您自己的域进行代理(e.g。/api/posthog)。这使 connect-src 保持在同一来源并免受广告拦截器的影响。
  2. PRE — CSP-allowlist the rest. 对于 Google Analytics、Stripe.js、Sentry、Intercom、GTM 等,将每个供应商的来源添加到匹配的 CSP 指令中(script-src 用于加载程序,connect-src 用于遥测,frame-src 用于 iframe,img-src 用于像素)。
  3. PRE — Use Stripe Checkout, not raw card forms. Stripe Checkout 是顶级重定向;该脚本不需要 CSP 条目。托管PCI 表面完全位于Stripe 的域中。仅当您有充分的理由时才自行推出。
  4. PRE — Lock package-lock.json in CI. 在生产版本中运行npm ci(不是npm install)。在每次发布之前使用 npm audit 或 Snyk 审核依赖关系。
  5. POST — Watch Technology Fingerprinting. 被动技术堆栈发现显示爬虫可见的库版本。如果您发布 EOL React、jQuery 或 Bootstrap,FixVibe 会对其进行标记并链接到已知的 CVE。

部署卫生和基础设施(8 项)

部署方式与部署内容同样重要。 AI-编码的应用程序尤其受益于显式部署强化。

  1. PRE — Disable x-powered-by. 在next.config.js 中:poweredByHeader: false。删除免费版本公开信号。
  2. PRE — Confirm middleware lives at src/middleware.ts. 对于src/ 目录布局,Next.js 会忽略根级别middleware.ts。错误放置的中间件无法设置 CSP / 身份验证标头 / 速率限制。
  3. PRE — Sanity-check Vercel deployment protection. Pro归纳应该是公开的;预览应受密码保护或仅限于组织成员。 Vercel-Specific Exposure 报告表面。
  4. PRE — Block dotfile and config probes at the edge. 为/.env、/.git/*、/.aws/*、/.next/trace 模式添加重写或拒绝规则。默认情况下,Vercel 对其中许多返回 403;交叉检查。
  5. DEPLOY — Separate environments. Pro归纳、预览、开发。每个人都有自己的一套秘密。实时键永远不会达到预览,Stripe测试模式永远不会达到Pro归纳。
  6. DEPLOY — Enable Vercel Web Application Firewall. Pro 和企业计划包括带有托管规则的WAF。 Cloudflare Pages 有机器人战斗模式。两者都减少了自动扫描仪的滥用和密码喷射负载。
  7. POST — Verify TLS configuration. SSL 实验室或 testssl.sh 针对您的生产域。 TLS 最低 1.2,首选 TLS 1.3,无弱密码,HSTS 预加载合格。
  8. POST — Confirm health-check endpoints are minimal. /api/health 应该返回没有主体的200 OK。不要在未经身份验证的情况下回显环境、构建哈希或部署时间戳。

持续监控和重新扫描(4 项)

安全不是一次性的装船前审核。每次部署都会发生漂移。

  1. Verify your production domain in FixVibe. Dashboard → Domains → DNS TXT or HTTP file verification. Active scans require Hobby or above, scheduled scans require Pro or Unlimited, and live threat monitoring requires Unlimited.
  2. Schedule passive re-scans on Pro or Unlimited. Choose an available cadence for your verified domain. Scheduled runs share your scan allowance; enable completion notifications and signed webhooks as needed. A scheduled scan observes the app at run time, not continuously.
  3. Wire outbound webhooks. Account → Webhooks → 添加HTTPS端点,订阅scan.completed + finding.created + scan.active_api.first_used。路由到 Slack / Discord / PagerDuty。
  4. Enable live threat monitoring on Unlimited. Periodic certificate, DNS, bundle, and threat-intelligence checks can surface changes between scheduled scans. Coverage and alert timing depend on the signal and successful polling.

Replit Agent

If you build with Replit Agent, also check:

  1. Don't paste keys into the Agent prompt. Add them in Secrets and give the Agent the variable name instead, so the value never appears in generated code or chat history.
  2. Test CORS on the production domain. The preview pane and your deployed URL are different origins. Check your CORS allowlist against the domain users actually load.
  3. Replit Agent sometimes hardcodes test values. 代理可能会生成带有API_URL = 'http://localhost:5000</code> 的代码。发货前,替换为<code>os.environ[API_URL']。

Firebase Studio

If you build with Firebase Studio, also check:

  1. Test-mode rules are temporary by intent, not by default. Test mode lets anyone read and overwrite data. If the generated rule carries a date cutoff, client access stops on that date; if not, the database stays open. Replace test rules before launch either way.
  2. Security rules protect data, not Hosting. Firestore and Storage rules don't govern what Firebase Hosting serves: everything in the public directory is public. Keep exports, backups and admin pages out of it.

Claude Code

If you build with Claude Code, also check:

  1. PRE — Keep personal Claude Code settings out of git. Commit .claude/settings.json for shared project settings, but keep .claude/settings.local.json out of the repo: Claude Code excludes it from git when it creates the file, so check it if you created it by hand. Session history lives in ~/.claude, outside the project (Claude Code docs).
  2. Bash operations are unverified. Claude Code 直接执行bash命令。 git commit -m "fix" 很方便,但如果工作目录有一个 .env 文件并且 glob 包含它,它就会提交。始终在Claude Code 提交之前检查git diff --cached。

后续步骤

想要了解这些项目为何重要的教育背景吗?阅读AI-generated code security scanning。想要每个强化步骤的具体代码片段吗?请参阅How to secure an app built with AI coding tools。

// scan your app

别再读了,去找你应用里的漏洞。

Drop in a URL — FixVibe runs every passive check from this guide plus the rest of its 230+ passive checks, usually in under a minute. Free, no install, no card.

  • Free 层 — 每月 3 次扫描,无卡。
  • 针对任何 URL 进行被动扫描 — 无需域验证。
  • 针对 Cursor、Claude Code、Lovable、Bolt、v0、Replit 进行了调整。
  • Coding-agent prompts for code/config findings, plus operator steps for DNS/provider fixes.
Vibe coding 安全检查清单:上线前 51 项 · FixVibe