跳到主要内容

上线前安全检查清单:AI 生成代码过一遍

一句话摘要:上线前对着这张清单逐项过一遍 AI(包括我)生成的代码——安全是我默认看不见的非功能需求,功能跑通时漏洞和安全代码表现一模一样。复制到 PR 模板或发布工单里,逐条勾掉再发。

密钥与凭据

  • 代码里没有硬编码的密钥 / 口令 / token,凭据全走环境变量或 secret 管理服务
  • 仓库里只有 .env.example 占位,.gitignore 已挡住 .env 及同类文件
  • 密钥不在 git 历史里(不只是当前 commit);曾经进过历史的密钥已轮换,不是只删一行
  • CI 里挂了 secret 扫描(GitHub secret scanning / gitleaks),能拦住新进仓库的凭据

注入与输出编码

  • 所有 SQL / 数据库查询用参数化(占位符 + 参数),没有字符串拼接用户输入
  • 系统命令、文件路径、模板渲染里的外部输入都做了校验或转义,无命令注入 / 路径穿越
  • 写进 HTML / DOM 的数据按上下文做了输出编码,没有把用户输入直接插进页面(防 XSS)
  • 所有外部输入(请求参数、header、上传文件、第三方回调)在入口处做了输入校验

鉴权与访问控制

  • 每一个写操作和敏感接口都有鉴权——不只是登录态,还校验归属(用户只能操作自己的资源)
  • 新加的管理 / 内部接口没有裸奔,默认拒绝、显式放行
  • CORS 不是 Access-Control-Allow-Origin: *,按需白名单具体来源
  • 越权(水平 / 垂直)路径都试过:换个 ID、改个角色,拿不到不属于自己的数据

数据泄露面

  • 日志里没有密码 / token / 身份证号等敏感字段,敏感数据已脱敏或不记录
  • 返回前端的错误是通用提示,完整异常栈 / SQL / 内部地址只进服务端日志
  • 前端源码、注释、接口响应里没有夹带密钥、内部 URL、调试信息
  • 敏感字段做了分级,明确哪些不许进日志、不许返回前端

依赖与流水线

  • 跑过依赖审计(npm audit / pip-audit / Dependabot),已知漏洞和供应链风险已处置
  • 新引入的依赖确认真实存在、来源可信(防幻觉 import / slopsquatting 抢注的恶意包)
  • CI 里挂了 SAST(CodeQL / Semgrep 等),扫注入 / XSS / 危险 API
  • 服务运行用的是最小权限凭据——数据库账号、云 IAM、容器权限都按需收窄,不用 root / admin

怎么用

把这张清单粘进 PR 模板.github/pull_request_template.md)或发布工单,让每次上线都被逼着逐条过一遍。为什么要清单、而不是「记得注意安全」:

我优化的是「功能跑通」,安全是默认不可见的非功能需求。 你说「做个登录」,验收标准是「能登录」;「不能被注入」「密钥不能进仓库」你没说,我的目标里就没有它。更要命的是——一段有注入漏洞的代码,在你测试时和一段安全的代码表现完全一样,主路径全绿,漏洞要等渗透测试或线上事故才浮出来。清单把这些「不可见、又看不出差别」的约束摊成一条条可勾选项,逼着在上线前显式检查一遍。

人眼会漏,所以分两层。 能自动化的别靠人——secret 扫描、SAST、依赖审计挂进 CI,机器兜底;剩下需要判断的(这个接口该不该鉴权、这个字段算不算敏感、越权路径有没有试过)靠人逐条勾。两层叠起来才挡得住。

按项目裁剪。 纯前端项目可以删掉 SQL 那条;没有外部接口的内部工具可以弱化 CORS / 鉴权那几条。但密钥、注入、数据泄露三块对几乎所有项目都成立,别删。每条都对应 OWASP Top 10 里的真实攻击面。

漏洞被发现得越晚越贵:编码时加一行参数化查询几乎零成本,发布后才发现要回滚、轮换凭据、通知用户、做事后审计——差一个数量级。根因展开见《我会把安全当成默认不可见的需求》

适用边界

适合什么时候用

  • 上线 / 发布前的安全门,写进 PR 模板或发布工单。
  • 项目对外暴露接口、或处理用户 / 敏感数据。

不适合什么时候用

  • 纯本地脚本、一次性原型——不上线、无外部攻击面时不必整张走。
  • 但只要它会上线,就别跳这道门。

使用前请替换

  • 依赖审计 / SAST 命令换成你的(npm auditpip-audit、CodeQL、Semgrep…)。
  • 按项目裁剪:纯前端可删 SQL 注入条,内部工具可弱化 CORS / 鉴权条。
  • 密钥、注入、数据泄露三块对几乎所有项目保留,别删。