为什么 AI 项目的安全风险更高?
三个原因:第一,AI 参考的公开代码本身就带着坏习惯,示例代码为了可读性经常硬编码密钥;第二,AI 分不清哪些是示例占位符、哪些是你粘贴进去的真实密钥;第三,人对 AI 生成配置的审查远少于自己手写的代码。结果是同一类问题反复出现——它们高度模式化,也因此非常适合自动化检查。
P0:明文密钥——发现即阻断部署
最典型的四类:
.env/.env.local被提交进 Git,或被打进构建产物- 代码里硬编码的 API Key、数据库密码、JWT Secret
- 私钥和证书文件(
*.pem、id_rsa)出现在仓库里 - 云厂商 AccessKey 明文出现在配置或前端代码中
关键认知:已经提交过 Git 的密钥等于已经泄漏。仅仅「从代码里删掉」没有意义——历史记录里还在,而扫描器全天候在扫公开仓库。正确动作是:① 立即到服务商控制台作废/轮换该密钥;② 从代码移除改用环境变量;③ 提交 .env.example 模板,并把 .env 加入 .gitignore。
P0 / P1:危险配置
| 配置 | 风险 | 处理 |
|---|---|---|
| DEBUG=True | 报错堆栈暴露源码路径、环境变量、SQL 语句 | 生产环境必须关闭 |
| 默认账号 admin/admin | 任何人都能登录后台 | 初始化后改强密码或禁用 |
| CORS 允许 * | 任意网站可携带凭证调用你的 API | 收紧到具体域名白名单 |
| 管理后台无鉴权 | /admin 页面在公网裸奔 | 加认证,必要时加 IP 白名单 |
| 数据库端口暴露公网 | 被暴力破解和勒索软件扫描 | 只允许内网/指定 IP 访问 |
P1:依赖漏洞
- 上线前跑一遍
npm audit/pip-audit,高危项清零或明确豁免理由 - 提交 lock 文件(package-lock.json / poetry.lock),锁定可复现的版本
- 注意:AI 倾向于安装训练数据里的旧版本包,装包时留意明显过时的主版本
P1 / P2:数据泄漏
容易忽视的一类:seed 脚本里的「测试数据」如果是真实手机号、身份证、邮箱,上线后就变成了数据泄漏事故。检查三处:种子数据是否脱敏、仓库里有没有 .sql dump 或备份文件、日志是否打印密码和 token。
风险分级与处理策略
| 等级 | 定义 | 处理策略 |
|---|---|---|
| P0 Critical | 明文密钥、无鉴权管理入口、数据库公网裸奔 | 阻断部署,修复后重新扫描 |
| P1 High | DEBUG 开启、CORS 全开、高危依赖、默认凭证 | 修复后再进入部署流程 |
| P2 Medium | 缺少安全响应头、日志含敏感信息、测试数据未脱敏 | 可先出 Preview,正式上线前必须处理 |
| P3 Low | 建议项:依赖版本偏旧、缺少限流 | 记录并排入后续迭代 |
上线前安全检查清单
- 全仓库搜索密钥特征:AKID、sk-、BEGIN PRIVATE KEY、password=
- .env 不在 Git 历史中(用 git log 全量确认,而不只是当前目录)
- 生产配置无 DEBUG,报错页面不暴露堆栈
- CORS 已白名单化,凭证模式仅限指定域名
- 管理入口有鉴权,默认账号已处置
- 数据库、Redis 不监听公网
- 依赖高危漏洞清零或有书面豁免
- 种子数据和日志已脱敏
- API 有关键接口的频控(登录、验证码、支付回调)
结语
安全预检的目标不是「绝对安全」,而是把最常见的、可自动化发现的问题在上线前拦住。这份清单正是宇视星上线服务中 Preflight Security Gate 的检查口径——发现 P0 项时,我们会先阻断部署,修复后重扫再放行。