如果你用 Claude 或 Cursor 快速编写了一个应用,现在准备交给付费客户,停下来。AI 生成的代码会带来可预见的安全漏洞——暴露的 API 密钥、缺失的输入验证、默认数据库权限让任何用户都能看到其他人的数据。这些不是边界情况。几乎每个首次 AI 生成的代码库都会出现这些问题。
这个指南是上线前的安全检查清单。在任何真实用户接触你的应用前,一步步跟着做。它是为最常见的快速编码堆栈编写的(Next.js + Supabase + Vercel),但这些原则适用于任何工具。
为什么 AI 生成的代码存在安全问题
AI 模型优化的是"它能工作吗?"而不是"它安全吗?"当你告诉 Claude "给我构建一个有用户账户的任务管理器"时,它会生成创建用户、存储任务和显示任务的代码。但它可能不会自动做的是:确保用户 A 看不到用户 B 的任务、验证输入字段不能接受恶意脚本、隐藏你的 API 密钥不被浏览器开发者工具看到,或添加速率限制来防止有人攻击你的端点。
这些不是 AI 的失败——它们是提示中的差距。AI 构建你要求的东西。你可能没有要求安全,因为你专注于功能。现在是时候回过头去添加它了。
第 1 步:审计你的环境变量
这是快速编码应用中最常见且最危险的错误。检查项目中的每个文件是否有硬编码的 API 密钥、数据库 URL 或机密。
要查找什么:在代码库中搜索以 sk-、eyJ、sbp_、supabase、postgres:// 开头的字符串,或任何看起来很长的随机字符串。专门检查这些文件:/app 或 /pages 目录中的任何文件、任何组件文件、你的 next.config.js 和任何工具文件。
修复方法:将每个机密移到环境变量中。在 Next.js 中,只有以 NEXT_PUBLIC_ 前缀的变量才会暴露给浏览器。你的数据库 URL、服务角色密钥和 API 机密永远不应该有这个前缀。
# .env.local(永远不要提交此文件)
SUPABASE_SERVICE_ROLE_KEY=your-secret-key
DATABASE_URL=postgres://...
# 这些可以暴露给浏览器:
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
验证:检查你的 .gitignore 文件是否包含 .env.local。如果你已经将机密提交到 Git,即使删除后它们仍在历史记录中——立即轮换(重新生成)每个暴露的密钥。
第 2 步:在 Supabase 中启用行级安全
如果你使用 Supabase,这是最关键的一步。默认情况下,Supabase 表没有访问限制——拥有你的匿名密钥的任何人都可以读写每个表中的每一行。这意味着用户 A 可以通过一个简单的 API 调用看到用户 B 的数据。
修复方法:在每个表上启用行级安全 (RLS),然后创建限制访问的策略。
进入你的 Supabase 仪表板 → 表编辑器 → 选择每个表 → 点击"RLS 已禁用"来启用它。然后添加策略:
对于典型应用,用户应该只看到自己的数据,创建一个 SELECT 策略:auth.uid() = user_id。为 INSERT、UPDATE 和 DELETE 创建类似的策略。
测试:以用户 A 身份登录,尝试通过 API 访问用户 B 的数据。如果你能看到它,你的策略有问题。Supabase 有一个 SQL 编辑器,你可以直接测试策略。
常见 AI 错误:Claude 经常生成使用 service_role 密钥的 Supabase 查询(绕过 RLS),而不是使用具有适当 RLS 策略的 anon 密钥。检查你的客户端代码是否仅使用匿名密钥。服务角色密钥只应存在于服务器端代码(API 路由、服务器操作)中,永远不要暴露给浏览器。
第 3 步:正确添加身份验证
AI 生成的身份验证代码通常可以工作,但采用了快捷方式。检查这些具体问题:
会话管理:确保会话过期。检查你的身份验证设置是否包含合理的会话超时(Supabase 默认值通常不错,但要验证)。确保登出实际上使会话失效,而不仅仅是清除本地 cookie。
密码要求:如果你有电子邮件/密码身份验证,强制执行最小密码长度(8+ 字符)。Supabase 在你的项目设置 → 身份验证 → 密码要求中处理此问题。
受保护的路由:显示用户特定数据的每个页面都需要身份验证中间件。在 Next.js App Router 中,创建一个检查有效会话的中间件,并将未经身份验证的用户重定向到登录页面。不要仅依赖客户端检查——用户可以通过直接调用你的 API 来绕过这些。
电子邮件验证:在 Supabase Auth 设置中启用电子邮件确认。这可以防止人们使用虚假电子邮件地址创建账户,并添加基本的账户有效性层。
从中获得价值?我们每周发布一篇关于 AI 工具、工作流和实用指南的深度探讨。加入抢先看的读者 →
第 4 步:验证所有输入
AI 生成的表单通常有基本验证(必填字段、电子邮件格式),但很少防止恶意输入。
要添加什么:
在每个 API 端点上进行服务器端验证。永远不要仅依赖客户端验证——它可以通过直接向 API 发送请求而被绕过。使用 Zod(适用于 TypeScript)等验证库为应用接受的每条数据定义架构。
清理呈现在浏览器中的任何用户生成内容中的 HTML。如果你的应用有评论、描述或任何呈现在浏览器中的文本字段,请使用 DOMPurify 等库来删除危险的脚本。没有这个,有人可以注入 JavaScript 来窃取其他用户的会话(跨站脚本 / XSS)。
如果你的应用接受文件上传,限制文件上传大小和类型。AI 生成的上传处理程序通常没有限制,这意味着有人可以上传 2GB 文件或可执行文件。添加大小限制(5MB 对大多数应用来说是合理的)并将文件类型限制为你实际需要的(图像、PDF 等)。
第 5 步:保护你的 API 路由
检查你的应用中的每个 API 路由或服务器操作是否存在这些问题:
每个端点上的身份验证。返回或修改用户数据的每个 API 路由都应该首先验证用户的会话。AI 经常生成接受来自任何人的请求的 API 路由。
身份验证之外的授权。即使确认了用户已登录,也要验证他们是否被允许访问他们正在请求的特定资源。"用户 A 已登录"并不意味着"用户 A 可以编辑用户 B 的配置文件"。在每次数据访问时检查所有权。
速率限制。没有速率限制,有人可以每秒向你的 API 发送数千个请求,要么刮取数据,要么压倒你的服务器。使用 rate-limiter-flexible 等库添加基本速率限制,或在边缘函数上使用 Vercel 的内置速率限制。
HTTP 方法。确保你的 API 路由只响应它们应该响应的 HTTP 方法。处理 POST 请求的路由不应该也响应 DELETE 请求,除非你明确设计了它。
第 6 步:检查你的部署配置
你的部署平台有 AI 不会为你配置的安全设置。
要检查的 Vercel 设置:启用"部署保护"(需要身份验证来查看预览部署——防止客户端意外共享公开正在进行的工作的预览 URL)。设置支出限制以防止你的应用获得流量激增时的意外费用。在 CORS 头中配置允许的域。
自定义域和 SSL:如果你将其交付给客户端,请使用 HTTPS 设置他们的自定义域。Vercel 和 Netlify 会自动处理 SSL。永远不要在 .vercel.app 子域上交付客户端应用——看起来不专业,客户端也不能轻易转移它。
头部:将安全头部添加到你的 next.config.js 或 vercel.json 中:X-Content-Type-Options: nosniff、X-Frame-Options: DENY(防止你的站点被嵌入在 iframe 中用于点击劫持)、Strict-Transport-Security(强制 HTTPS)。这些是一次性添加,可防止整类攻击。
第 7 步:运行最终安全扫描
在将任何内容交付给客户端前,运行这些免费检查:
npm audit:在你的项目目录中运行 npm audit。它标记你的依赖项中的已知漏洞。修复严重和高严重性问题。在有可用的地方运行 npm audit fix 进行自动修复。
Lighthouse:在 Chrome 中打开你的已部署站点,打开开发工具,运行 Lighthouse 审计。检查"最佳实践"评分——它捕获常见安全问题,如缺失 HTTPS、易受攻击的库和不安全的头部。
手动测试:以一个用户身份登录,尝试通过修改 URL 或 API 调用来访问另一个用户的数据。尝试提交空表单、超大输入和特殊字符(如编码的 XSS 有效负载)。如果这些中的任何一个有效,你有问题需要修复。
上线前检查清单
打印这个并在上线前检查每个项目:
- 所有机密都在环境变量中(没有硬编码的密钥)
.env.local在.gitignore中(并且 Git 历史中没有机密)- 在每个表上启用 Supabase RLS
- RLS 策略已测试(用户 A 看不到用户 B 的数据)
- 客户端代码仅使用匿名密钥(服务角色密钥仅在服务器端)
- 每个 API 路由上都有身份验证
- 授权检查(所有权验证)关于数据访问
- 每个表单上都有输入验证(服务器端,不仅仅是客户端)
- 文件上传限制(大小和类型),如果适用
- API 端点上的速率限制
- 已配置安全头部
npm audit已运行并修复了严重问题- 已配置带 SSL 的自定义域
- 预览部署受保护
- 手动跨用户数据访问测试已通过
底线
保护快速编码的应用不是关于成为安全专家。它是关于运行一个检查清单,捕获 AI 留下的可预见的差距。上面的步骤需要 2–4 小时,并防止最常见的漏洞。对于面向客户端的应用,这不是可选的——这是专业工作和责任之间的区别。
如果你正在构建你的第一个快速编码应用,从我们的快速编码完整指南开始。如果你想改进与 Claude 或 Cursor 一起使用的提示,请尝试我们的免费提示优化器。关于最佳编码工具的分解,请参阅Claude Code vs Codex。
这是我们每周所做的。关于 AI 工具、工作流和诚实观点的深度探讨——没有炒作,没有填充物。加入我们 →
披露:本文中的某些链接是附属链接。我们只推荐我们个人测试过并定期使用的工具。查看我们的完整披露政策。