Skip to content

11.4 测试与安全最佳实践

🎯 本节目标

学习如何通过测试驯服 AI 生成的代码,以及如何避免常见的安全陷阱。


🧪 测试:比以往更重要

为什么 AI 时代测试更重要?

AI 代码的特点:
├── 通常能生成"正确"的代码
├── 但可能误解规格(做了错误的事情)
├── 有时会出现幻觉
└── 人类也会误解需求,这不是 AI 独有的问题

结论:测试是验证 AI 输出的关键手段

即使我们达到了完全的人工通用智能(AGI),测试依然重要——因为人类也会误解规格!

TDD(测试驱动开发)与 AI

markdown
TDD + AI 的工作流:

1. 先写测试骨架
   ├── 定义期望的输入和输出
   └── 明确边界条件

2. 让 AI 实现代码
   ├── AI 看到测试就知道目标
   └── 有明确的成功标准

3. 运行测试验证
   ├── 让 AI 自己运行测试
   └── 失败时自动修复

4. 测试通过后继续
   └── 只有通过所有测试才继续下一个功能

属性测试(Property-Based Testing)

属性测试特别适合 AI 生成的代码:

普通测试 vs 属性测试:

普通测试:
assert sort([3, 1, 2]) == [1, 2, 3]
# 只测试了一个特定输入

属性测试:
@given(lists(integers()))
def test_sort_preserves_length(lst):
    assert len(sort(lst)) == len(lst)
# 测试了无数个随机输入

优势:

  • 覆盖边界情况
  • 发现你没想到的 bug
  • 即使 AI 后续修改代码,属性测试仍然有效

属性测试库

语言链接
Pythonhypothesishypothesis.readthedocs.io
JavaScript/TypeScriptfast-checkfast-check.dev
其他语言搜索 "property-based testing + [语言]"-

测试陷阱警告

⚠️ AI 作弊行为

有时候 AI 会"作弊"来让测试通过:
├── 硬编码预期输出
├── 检测测试输入并返回固定值
└── 绕过实际逻辑

解决方案:
├── 审查测试和实现代码
├── 使用属性测试(难以作弊)
└── 测试边界情况和随机输入

🔒 安全检查清单

核心原则

第一原则:永远不要信任 AI 生成的代码

AI 不会为你运行的代码负责——你自己负责!

安全检查清单

1. 密钥管理

markdown
❌ 绝对不要:
- 硬编码 API 密钥
- 在前端代码中存储密钥
- 将 .env 文件提交到 Git

✅ 正确做法:
- 使用环境变量
- 使用密钥管理服务(如 Vercel 的环境变量)
- 在 .gitignore 中添加敏感文件

2. 网络安全

markdown
❌ 绝对不要:
- 使用 HTTP(不加密)
- 禁用 SSL 验证
- 忽略证书错误

✅ 正确做法:
- 始终使用 HTTPS
- 验证 SSL 证书
- 使用安全的 API 端点

3. 输入验证

markdown
❌ 绝对不要:
- 信任用户输入
- 直接拼接 SQL 查询
- 在 HTML 中直接插入用户内容

✅ 正确做法:
- 验证和清理所有输入
- 使用参数化查询
- 转义 HTML 输出(防 XSS)

4. 客户端存储

markdown
❌ 绝对不要:
- 在 localStorage 存储敏感数据
- 在 cookies 存储密码
- 在 sessionStorage 存储令牌(某些场景)

✅ 正确做法:
- 使用 httpOnly cookies 存储令牌
- 加密敏感数据
- 最小化客户端存储的数据

5. 依赖安全

bash
# 定期扫描依赖漏洞

# npm
npm audit

# Python
pip-audit
safety check

# 通用
snyk test

🛡️ 安全工作流

在项目规则中添加安全约束

markdown
# .cursor/rules/security.md

## 安全规范

- 永不硬编码密钥或敏感信息
- 所有 API 调用必须使用 HTTPS
- 所有用户输入必须验证和清理
- 数据库查询必须使用参数化语句
- 前端不存储任何敏感数据
- 所有依赖必须定期审计

## 禁止清单

- 不使用 eval() 或类似函数
- 不禁用安全检查或 SSL 验证
- 不在日志中输出敏感信息
- 不使用过时的加密算法

代码审查重点

markdown
审查 AI 生成代码时关注:

1. 输入处理
   - 是否验证了所有外部输入?
   - 是否正确处理了边界情况?

2. 数据存储
   - 敏感数据如何存储?
   - 是否使用了适当的加密?

3. 网络通信
   - 是否使用了 HTTPS?
   - API 密钥如何传递?

4. 错误处理
   - 错误信息是否泄露了敏感信息?
   - 是否有适当的日志记录?

5. 依赖
   - 是否使用了已知有漏洞的包?
   - 依赖是否是最新版本?

📋 OWASP Top 10 快速参考

这些是最常见的 Web 应用安全风险:

排名风险AI 代码中常见吗?
1注入攻击(SQL、命令注入)⚠️ 常见
2认证失效⚠️ 常见
3敏感数据暴露⚠️ 非常常见
4XML 外部实体较少见
5访问控制失效⚠️ 常见
6安全配置错误⚠️ 常见
7XSS 跨站脚本⚠️ 常见
8不安全的反序列化较少见
9使用有漏洞的组件⚠️ 常见
10日志和监控不足常见

针对 AI 代码的特别关注

AI 生成代码中最常见的安全问题:

1. 硬编码的密钥
   AI 经常在示例代码中使用硬编码密钥

2. 缺少输入验证
   AI 倾向于"信任"输入数据

3. 过于宽松的权限
   为了"让代码工作"而开放过多权限

4. 过时的依赖
   使用训练数据中的旧版本库

🔍 安全扫描工具

静态分析工具

工具语言说明
ESLint Security PluginJavaScript发现 JS 安全问题
BanditPythonPython 安全分析
Semgrep多语言自定义规则扫描
Snyk多语言依赖和代码扫描

使用示例

bash
# JavaScript/TypeScript
npm install -D eslint-plugin-security
npx eslint --ext .js,.ts .

# Python
pip install bandit
bandit -r ./src

# 通用
npx snyk test

⚡ 快速安全检查清单

在部署前确认:

markdown
□ 没有硬编码的密钥或密码
□ 所有 API 调用使用 HTTPS
□ 用户输入已验证和清理
□ 数据库使用参数化查询
□ 前端没有存储敏感数据
□ 依赖已扫描无已知漏洞
□ 错误信息不泄露敏感信息
□ 认证和授权正确实现
□ 日志不包含敏感信息
□ CORS 正确配置

🔗 下一步

继续学习 11.5 工具与资源汇总 —— 获取完整的工具列表和学习资源!


📚 本节参考资源

基于 MIT 许可证发布。内容版权归作者所有。