// docs / security guides / pre-ship checklist
Vibe coding 安全检查清单:上线前 44 项
针对使用 Cursor、Claude Code、Lovable、Bolt、v0、Replit 和 Windsurf 构建的应用程序的实用的、分阶段组织的清单。每个项目都可以在五分钟内完成。在投入生产之前运行它,然后在每个主要版本之前再次运行它。项目分为七个类别——秘密、数据库、身份验证、标头、第三方、部署、监控——并标记有它们适用的部署阶段。
PRE = 预部署(审核您的源)。 DEPLOY = 在部署时。 POST = 部署后验证。相关项目参考FixVibe 检查category.check-id 表单中的ID。
秘密和API密钥(8项)
硬编码按键是振动编码应用程序中最常见的一个现象。八项措施可将其拒之门外:
- PRE — Audit
NEXT_PUBLIC_env vars. 任何以NEXT_PUBLIC_为前缀的内容都包含在客户端捆绑包中。如果其中一个是 Supabaseservice_role密钥(解码为 JWT 和"role":"service_role"),请将其删除并通过仅服务器客户端(src/lib/supabase/service.ts和import 'server-only')进行路由。 - PRE — Grep for hardcoded provider keys. 搜索
sk_live_、pk_live_、STRIPE_SECRET、sk-ant-、sk-、AIza、AKIA和 JWT- 查找字符串 (eyJ) 的源。将每个命中移至.env.local并仅通过process.env.*服务器端进行引用。 - PRE — Verify
.gitignore. 确认.env*.local、.npmrc、.yarnrc,并且任何特定于提供商的凭据文件都将被忽略。通过您的提供者模式运行git ls-files以查找已提交的任何内容。 - PRE — Scan the built bundle. 运行
npm run build,然后 grep.next/static和相同模式的任何dist/输出。如果密钥到达捆绑包,则开发人员永远不会进行干净的环境分离。 - DEPLOY — Set secrets per environment. Vercel:设置→环境变量,每个变量的范围为Pro归纳/预览/开发。切勿与预览环境共享
sk_live_*。使用Vercel 的加密环境变量存储,而不是内联工作流程机密。 - DEPLOY — Disable build-log secret echo. 构建期间的一些 CI 配置
echo环境变量。审核您的vercel.json、GitHub 操作工作流程或Cloudflare 页面设置,以查找任何会将值推送到公共构建日志中的echo $SECRET。 - POST — Run a passive scan. FixVibe 的Free 层涵盖了这一点:粘贴部署的URL,等待约20 秒,查找
secrets.*结果。 secrets.browser-storage 检查捕获通过误用SDK 而落在localStorage或sessionStorage中的键。 - POST — Rotate any key that ever shipped. 如果密钥在公共捆绑包中存在甚至几分钟,则将其视为已泄露。通过仪表板轮换 Supabase 服务角色密钥,重新生成 Stripe 受限密钥,通过控制台撤销 Anthropic / OpenAI / Google 密钥。
数据库访问控制:RLS和Firestore规则(6项)
BaaS 默认值是有意允许的,因此第一个教程有效。 Pro归纳需要明确的政策。
- PRE — Force RLS on every
public.*table. 在Supabase 中:每个表必须有ALTER TABLE ... ENABLE ROW LEVEL SECURITY和FORCE ROW LEVEL SECURITY。 Force 很重要:没有它,Postgres 会绕过表所有者的RLS。 - PRE — Write a policy per (table, role, action). 最小值:加入
auth.uid()的SELECT 策略。更好:单独的INSERT / UPDATE / DELETE 策略,这样UPDATE 就无法偷偷引入user_id重新路由所有权的更改。 - PRE — Replace default Firebase rules. 默认测试模式规则为
allow read, write: if true;。替换为每个集合的身份验证绑定规则:match /users/{userId}与allow read, write: if request.auth.uid == userId; - PRE — Lint migrations in CI. 在合并之前运行
supabase db lint或等效命令。如果任何CREATE TABLE public.*缺少匹配的RLS 策略,CI 应该使构建失败。 - DEPLOY — Confirm RLS survived deploy. 部署后重新检查Supabase Studio:表 → 每行 → RLS 切换为 ON。 Pro归纳数据库迁移有时会领先于策略文件;验证该政策是否有效。
- POST — Run an active scan against a verified domain. baas.supabase-rls 主动检查使用匿名键写入一个微小的种子行,并报告写入是否成功 - i.e。 RLS实际上并没有强制执行。
身份验证和会话(7 项)
AI-编码应用程序中的身份验证错误往往很微妙:令牌验证中的一对一偏差、丢失HttpOnly标志、getSession()(本应有getUser())。
- PRE — Replace
getSession()withgetUser().getSession()读取cookie并信任它;getUser()与Supabase 后端进行验证。在服务器路由上始终使用getUser()。 - PRE — Confirm token expiry. Magic-link、密码重置和电子邮件验证令牌需要服务器强制过期。默认Supabase 魔法链接会在 1 小时后过期——如果没有真正的原因,请勿将其覆盖为更高的数字。
- PRE — Verify JWT
audandexp. 如果您在任何地方手动解码令牌,请检查这两个声明。更好:使用 SDK 的getUser()来为你做这件事。 - PRE — Audit cookie flags. 自定义会话 cookie 应为
Secure; HttpOnly; SameSite=Lax(或Strict对于非OAuth 流)。localStorage中没有课程材料。 - PRE — Validate the
nextredirect param. 登录后的next查询参数必须以/开头,而不是//(打开重定向到attacker.example)。拒绝服务器端的任何其他内容。 - POST — Test logout. 登录、注销、检查 cookie(DevTools → 应用程序 → Cookies)。必须在同一响应中清除会话 cookie。如果它持续存在,则注销处理程序实际上并未破坏服务器端状态。
- POST — Active probe. active.auth-flow 和 active.account-enumeration 检查表面破坏的身份验证边界 - 对“用户存在”与“错误密码”的不同响应、缺少登录速率限制、未签名的重置令牌。
HTTP 安全标头和内容安全策略(6 项)
标头是整个管道中最便宜的强化,也是代码生成器最常跳过的。
- 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 自动应用随机数。 - PRE — Add the legacy three.
X-Content-Type-Options: nosniff、X-Frame-Options: DENY(或单独依赖CSPframe-ancestors)、Strict-Transport-Security: max-age=31536000; includeSubDomains。 - PRE — Tighten
Referrer-Policy. 默认strict-origin-when-cross-origin适用于大多数应用程序。不要发送unsafe-url或根本不发送标头。 - PRE — Replace
Access-Control-Allow-Origin: *. Grep 查找它。替换为明确的来源允许列表。无论*与credentials: include在一起,浏览器都会拒绝该请求——但这并不能防止后端配置错误。 - DEPLOY — Verify headers post-deploy. 打开 DevTools → 网络 → 单击根文档 → Headers 选项卡。 CSP、HSTS、X-Frame-Options、X-Content-Type-Options 应存在。 CSP 不得在
script-src中包含'unsafe-inline'。 - POST — Run headers.security-headers. 被动标头检查通过部署平台修复指南报告每个丢失的标头(Vercel
vercel.json、Cloudflare 页_headers、Netlify_headers、Next.js 中间件)。
第三方集成和APIs(5 项)
您包含的每个脚本都是CSP 豁免和潜在的供应链表面。将第三方视为您信任边界的一部分。
- PRE — Reverse-proxy analytics where possible. PostHog、Plausible、Umami 都支持通过您自己的域进行代理(e.g。
/api/posthog)。这使connect-src保持在同一来源并免受广告拦截器的影响。 - PRE — CSP-allowlist the rest. 对于 Google Analytics、Stripe.js、Sentry、Intercom、GTM 等,将每个供应商的来源添加到匹配的 CSP 指令中(
script-src用于加载程序,connect-src用于遥测,frame-src用于 iframe,img-src用于像素)。 - PRE — Use Stripe Checkout, not raw card forms. Stripe Checkout 是顶级重定向;该脚本不需要 CSP 条目。托管PCI 表面完全位于Stripe 的域中。仅当您有充分的理由时才自行推出。
- PRE — Lock
package-lock.jsonin CI. 在生产版本中运行npm ci(不是npm install)。在每次发布之前使用npm audit或 Snyk 审核依赖关系。 - POST — Watch discovery.tech-fingerprint. 被动技术堆栈发现显示爬虫可见的库版本。如果您发布 EOL React、jQuery 或 Bootstrap,FixVibe 会对其进行标记并链接到已知的 CVE。
部署卫生和基础设施(8 项)
部署方式与部署内容同样重要。 AI-编码的应用程序尤其受益于显式部署强化。
- PRE — Disable
x-powered-by. 在next.config.js中:poweredByHeader: false。删除免费版本公开信号。 - PRE — Confirm middleware lives at
src/middleware.ts. 对于src/目录布局,Next.js 会忽略根级别middleware.ts。错误放置的中间件无法设置 CSP / 身份验证标头 / 速率限制。 - PRE — Sanity-check Vercel deployment protection. Pro归纳应该是公开的;预览应受密码保护或仅限于组织成员。 discovery.platform-vercel 报告表面。
- PRE — Block dotfile and config probes at the edge. 为
/.env、/.git/*、/.aws/*、/.next/trace模式添加重写或拒绝规则。默认情况下,Vercel 对其中许多返回 403;交叉检查。 - DEPLOY — Separate environments. Pro归纳、预览、开发。每个人都有自己的一套秘密。实时键永远不会达到预览,Stripe测试模式永远不会达到Pro归纳。
- DEPLOY — Enable Vercel Web Application Firewall. Pro 和企业计划包括带有托管规则的WAF。 Cloudflare Pages 有机器人战斗模式。两者都减少了自动扫描仪的滥用和密码喷射负载。
- POST — Verify TLS configuration. SSL 实验室或 testssl.sh 针对您的生产域。 TLS 最低 1.2,首选 TLS 1.3,无弱密码,HSTS 预加载合格。
- POST — Confirm health-check endpoints are minimal.
/api/health应该返回没有主体的200 OK。不要在未经身份验证的情况下回显环境、构建哈希或部署时间戳。
持续监控和重新扫描(4 项)
安全不是一次性的装船前审核。每次部署都会发生漂移。
- Verify your production domain in FixVibe. Dashboard → Domains → DNS TXT 或 HTTP 文件验证。这可以解锁计划的重新扫描、主动探测和实时威胁监控。
- Schedule passive re-scans. Pro 计划支持 3 小时节奏; Unlimited 支持 6 小时节奏。每次显示新发现的计划扫描都会触发一封电子邮件(如果您已连接,还会触发一个网络钩子)。
- Wire outbound webhooks. Account → Webhooks → 添加HTTPS端点,订阅
scan.completed+finding.created+scan.active_api.first_used。路由到 Slack / Discord / PagerDuty。 - Enable live threat monitoring on Unlimited. 证书透明度日志差异、DNS 更改、JS 捆绑秘密泄露、威胁情报列表 — 在检测到它们时立即触发,而不是在下一次计划扫描时触发。
后续步骤
想要了解这些项目为何重要的教育背景吗?阅读AI-generated code security scanning。想要每个强化步骤的具体代码片段吗?请参阅How to secure an app built with AI coding tools。
