Week 6 中文导读:安全扫描(Security Scanning)
March 16, 2026 · View on GitHub
本周课程嘉宾:Isaac Evans,Semgrep CEO。他分享了用 AI 工具发现真实安全漏洞的经验,以及 AI 时代的安全测试策略。
Week 6 中文导读:安全扫描(Security Scanning)
这周在干什么
AI 能帮你快速写代码,但"快"不等于"安全"。这周你会学到:AI 生成的代码可能包含哪些安全漏洞(Vulnerability),以及如何用自动化工具来检测和修复它们。
这是整个课程中非常实用的一周。不管你将来用不用 AI 写代码,理解常见的安全问题都会让你成为更好的开发者。
为什么安全检查重要?
一个类比:AI 写代码就像一个非常高效但缺乏安全意识的实习生。他能快速完成任务,但可能会:
- 把密码直接写在代码里(硬编码密钥,Hardcoded Secrets)
- 把用户输入直接拼进数据库查询(SQL 注入,SQL Injection)
- 允许任何网站调用你的 API(CORS 配置不当)
- 使用过时的加密算法(比如 MD5)
这些问题在功能上可能完全正常——应用能跑,测试能过,用户能用。但在安全上是定时炸弹。一个 SQL 注入漏洞可能让攻击者读取你整个数据库的内容。
你可能会想:"我只是在做练习项目,安全没那么重要吧?"问题是,不安全的编码习惯一旦养成,很难在"真正重要"的项目中突然改掉。现在就养成好习惯,将来省很多麻烦。
Semgrep 是什么?
Semgrep 是一个代码扫描工具,类似代码的"安检机"。它用预定义的规则(Rules)扫描你的代码,找出常见的安全问题和代码质量问题。
和 lint 工具(比如 ESLint、pylint)不同的是,Semgrep 专注于安全相关的问题,而且支持多种编程语言。
Semgrep 的三种扫描类型
理解这三种类型很重要,因为它们检测的问题完全不同:
1. SAST(Static Application Security Testing,静态应用安全测试)
直接分析你写的源代码,找出不安全的编码模式。比如:
- 你在代码里拼接 SQL 字符串 → 它会提醒你用参数化查询(Parameterized Query)
- 你用了不安全的函数 → 它会建议安全的替代方案
2. Secrets(密钥检测)
扫描代码中硬编码的敏感信息。比如:
- API Key 直接写在代码里
- 数据库密码出现在配置文件中
- AWS 访问密钥被提交到 Git
这类问题特别常见于 AI 生成的代码——因为 AI 在生成示例时,经常会"编造"一个看起来像真实密钥的字符串,而你可能没注意就直接用了。
3. SCA(Software Composition Analysis,软件成分分析)
检查你项目依赖的第三方包(比如 npm 包、pip 包)是否有已知的安全漏洞。这不是检查你的代码,而是检查你用的别人的代码。
比如你的 requirements.txt 里用了某个版本的 Flask,而这个版本有已知的安全漏洞,SCA 就会提醒你升级。
常见安全问题(本周可能遇到的)
SQL 注入(SQL Injection)
不安全的写法:
# 千万别这么写
query = f"SELECT * FROM users WHERE name = '{user_input}'"
如果 user_input 是 '; DROP TABLE users; --,你的整个用户表就没了。
安全的写法:
# 用参数化查询
query = "SELECT * FROM users WHERE name = ?"
cursor.execute(query, (user_input,))
硬编码密钥(Hardcoded Secrets)
不安全的写法:
API_KEY = "sk-1234567890abcdef"
安全的写法:
import os
API_KEY = os.environ.get("API_KEY")
不安全的 CORS 配置
不安全的写法:
# 允许所有来源访问——相当于把门完全打开
app.add_middleware(CORSMiddleware, allow_origins=["*"])
安全的写法:
# 只允许特定的前端域名访问
app.add_middleware(CORSMiddleware, allow_origins=["https://myapp.com"])
弱加密(Weak Cryptography)
不安全的写法:
import hashlib
password_hash = hashlib.md5(password.encode()).hexdigest()
安全的写法:
import bcrypt
password_hash = bcrypt.hashpw(password.encode(), bcrypt.gensalt())
MD5 和 SHA1 在安全场景下已经不够用了。用 bcrypt、scrypt 或 argon2 来处理密码。
任务导读
原始作业(assignment.md)的核心流程是:
第一步:运行 Semgrep 扫描
按照 assignment.md 中提供的命令运行扫描。Semgrep 会输出一份报告,列出它发现的所有问题,包括:
- 问题描述
- 所在文件和行号
- 严重程度(severity)
- 建议的修复方式
第二步:选择 3 个问题修复
从扫描结果中挑 3 个你能理解的问题来修复。建议挑不同类型的问题(比如一个 SAST、一个 Secrets、一个 SCA),这样你的学习覆盖面更广。
第三步:记录修复过程
对每个修复,你需要说清楚三件事:
- 问题是什么:Semgrep 报了什么
- 为什么危险:这个问题在真实场景中可能造成什么后果
- 你怎么修的:具体改了什么代码
这个记录过程很重要——它迫使你理解问题的本质,而不是机械地按建议改代码。
与主题线的连接
Agentic Coding 不只是"让 AI 帮你写代码",还包括"确保 AI 写的代码是安全的"。安全扫描应该成为你使用 AI 编码后的标准流程——就像飞行员起飞前的检查清单(Preflight Checklist)。
这也是 Vibe Coding 和专业开发的一个重要区别:专业开发者会检查 AI 的输出。不是因为不信任 AI,而是因为任何人(包括 AI)写的代码都应该经过安全检查。
在你的日常工作流中,可以考虑把 Semgrep 扫描加入到以下环节:
- 每次让 AI 生成代码后
- 每次提交代码前(可以用 pre-commit hook 自动化)
- 定期对整个项目进行全面扫描
环境准备
1. 安装 Semgrep
Semgrep 是开源的静态分析工具。安装方式参考 Semgrep GitHub。
你可以选择使用 Semgrep Appsec Platform(网页版)或 CLI 工具(命令行版)。
2. 扫描范围
本周需要扫描的内容:
- 后端 Python 代码:
week6/backend/ - 前端 JavaScript 代码:
week6/frontend/ - 依赖包:
week6/requirements.txt - 配置/环境文件(检查密钥泄露):
week6/目录下的文件
练习任务
第一步:运行安全扫描
从仓库根目录运行以下命令:
semgrep ci --subdir week6
这个命令会使用 CI 规则集(包含代码规则和密钥检测规则)扫描 week6/ 目录。
第二步:选择 3 个问题并修复
从 Semgrep 扫描结果中选择任意 3 个问题,使用你选择的 AI 编码工具修复它们。
对每个修复:
- 记录文件和行号
- 记录 Semgrep 标记的规则/类别
- 简要说明风险
- 展示你的修改(代码差异或说明,以及 AI 工具的使用)
- 解释为什么你的修改能消除风险
第三步:验证
重要:修复后确保应用仍然可以运行,测试仍然通过。每次修复后重新运行 Semgrep 确认问题已解决且没有引入新问题。
修复参考方向
常见的修复方式包括:
- 参数化 SQL 查询(防止 SQL 注入)
- 使用更安全的 API
- 更强的加密算法
- 净化 DOM 写入(防止 XSS)
- 限制 CORS 配置
- 升级依赖版本
成果要求
- 扫描概览:总结 Semgrep 报告的问题类别(SAST/Secrets/SCA),说明误报(False Positive)和忽略的规则
- 三个修复:每个包含文件位置、规则类别、风险描述、修改内容、修复原理
自检清单
- 理解为什么 AI 生成的代码需要安全检查
- 成功运行了 Semgrep 扫描
- 修复了至少 3 个安全问题
- 能解释每个修复为什么能消除风险
- 理解 SAST、Secrets、SCA 三种扫描类型的区别