franktomasello/ai-assisted-dev-security-demo
GitHub: franktomasello/ai-assisted-dev-security-demo
通过三个实际漏洞场景演示 GitHub Advanced Security 如何在 CI/CD 流程中自动捕获并修复 AI 生成代码里的安全隐患。
Stars: 0 | Forks: 0
# 🛡️ AI 辅助开发安全演示
**演示 GitHub Advanced Security (GHAS) 如何捕获 AI 生成代码中的漏洞。**
[](https://github.com/features/security)
[](https://codeql.github.com/)
[](https://docs.github.com/en/code-security/secret-scanning)
[](https://github.com/features/security)
## 📖 问题描述
像 GitHub Copilot 这样的 AI 编程助手生成代码的速度非常快——而且很多代码看起来都是正确的。
但速度和自信并不等于安全。AI 可能会悄无声息地引入安全漏洞:
不安全的代码模式、硬编码的 secret 以及有风险的依赖项。由于输出看起来
非常完善,开发人员在审查它们时,往往不如审查同事的代码那样仔细——
因此,当代码发布量更大时,人工安全检查反而变弱了。
这个 repo 通过三个真实的场景展示了安全网的作用,每个场景都有你在
下方文件中可以阅读的代码作为支撑。
## 🚀 工作原理
```
Developer uses AI assistant
│
▼
AI generates code ──────────────────────────────────┐
│ │
▼ ▼
Opens Pull Request May contain vulnerabilities:
│ • SQL Injection
▼ • Hardcoded secrets
GitHub Advanced Security • Insecure dependencies
automatically scans: • XSS / Path traversal
│
▼
Vulnerabilities surfaced in PR
before merge ✅
```
## 📂 仓库内容
这个 demo 刻意做得很小——只有少量的 Python 文件,每个文件代表一种
AI 助手可能引入的不同类型的漏洞。
| 文件 | 用途 |
|---|---|
| `user_lookup.py` | Flask 的 `/user` endpoint,用于在 SQLite 数据库中查找用户——即 **SQL injection** 场景 |
| `payments.py` | `charge_customer()` 辅助函数,调用 payments API——即 **硬编码 secret** 场景 |
| `requirements.txt` | 固定 `flask` 和 `requests==2.19.1` 版本——即 **脆弱依赖项** 场景 |
| `test_user_lookup.py` | `unittest` 测试套件,断言用户查询使用了参数化查询 |
| `app.py` | 最简化的 `greet()` 示例,用作无害的基准文件 |
| `.gitignore` | 标准的 Python ignore 规则 |
## 🧪 三大场景
每个场景都从脆弱的、AI 生成的代码开始,被 GHAS 捕获,然后
进行修复。下方的说明描述了演示过程中发生的事情,以及**当前**
代码在 `main` 分支上的状态。
### 🔬 场景 1 — 不安全的代码模式 (SQL Injection)
提示 Copilot 编写一个用户查询。在倾向于使用 f-string 的引导下,它生成了:
```
query = f"SELECT * FROM users WHERE username = '{username}'"
cursor.execute(query)
```
用户输入直接流入了 SQL 字符串中——这是一个典型的注入漏洞。
**捕获方式:** CodeQL code scanning,被标记为*"SQL query built from user-controlled sources."*
**经验总结:** CodeQL 是一种数据流分析——只有当它能将不受信任的数据从
**source**(这里是 Flask 的 `request.args` 参数)追踪到一个危险的
**sink**(即 SQL 查询)时,它才会标记漏洞。一个没有可追踪来源的普通函数参数
没有被标记;而通过 web endpoint 暴露输入,则为 CodeQL 提供了它所需的
source→sink 路径。这是大多数假阴性/假阳性问题的根源。它还需要
`security-extended` 查询套件——默认套件旨在最大限度地减少噪音,因此
漏掉了它。
**当前状态:** ✅ 已修复。`user_lookup.py` 现在将值绑定为查询参数
(`WHERE username = ?`),并且 `test_user_lookup.py` 断言了该行为,因此该修复
不会悄然倒退。
### 🔑 场景 2 — 硬编码 Secret
Copilot 构建了一个包含内联 API key 的支付集成。使用了一个
格式逼真的(非在线)Stripe 测试 key,推送 commit 时触发了拦截。
**捕获方式:** Secret scanning 结合 **push protection**——该 commit 在
*secret 到达 repo 之前就被拦截了。*
**经验总结:** Secret scanning 是基于模式的。一个虚假的占位符
(`"your_api_key_here"`)不会触发它;而匹配已知服务商模式的凭证
则会触发。Push protection 在 commit 时阻止了泄露,而不是事后发出警告。
**当前状态:** ✅ 已修复。`payments.py` 从 `STRIPE_API_KEY`
环境变量中读取凭证——这是 push protection 引导你采用的
安全替代方案。
### 📦 场景 3 — 脆弱依赖项 (供应链)
在 `requirements.txt` 中添加了一个已知存在漏洞的软件包版本(`requests==2.19.1`)。
**捕获方式:** Dependabot——它列举了 **5 个已知的 CVE**(1 个高危,4 个中危),每个
都按严重程度和直接依赖项进行了标记。
**经验总结:** Dependabot 能干净利落地捕获来自 advisory
数据库的*已知*漏洞,并提供了安全团队所需的严重程度和直接/传递依赖项分类信息。其差距在于:一个全新的*恶意*软件包——例如
AI 助手产生幻觉并猜中攻击者预先注册的“slopsquat”名称——目前还没有 CVE,因此这正是
人类警惕性依然不可或缺的地方。
**当前状态:** ⚠️ 刻意保留漏洞。升级 `requests` 会掩盖那些使演示的
依赖部分值得展示的警报,因此除非你正在演示修复步骤本身,否则请保留该版本号不动。
### 待清理积压问题
现场演示录像中遗留的两个问题仍然存在于 `main` 上。它们**不属于**
演示的一部分——它们应该被清理掉,在这里列出只是为了让演示者不会对它们感到惊讶:
- `payments.py` 调用了 `os.environ.get(...)` 但从未导入 `os`,因此 `charge_customer()`
如果被执行会引发 `NameError`。在演示期间该文件只被读取,从未运行,
这就是为什么这个 bug 能存活下来的原因。**修复方法:** 添加 `import os`。
- 一个多余的 `.user_lookup.py.swp` Vim swap 文件被提交到了 repo 的根目录下。
**修复方法:** 删除它(根目录下的 `.gitignore` 也应该覆盖 `*.swp`)。
## ▶️ 在本地运行演示
```
# 1. 安装依赖(使用虚拟环境)
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
# 2. 运行 Flask user-lookup endpoint
flask --app user_lookup run
# 然后访问 http://127.0.0.1:5000/user?username=alice
# 3. 运行测试套件
python -m unittest discover -p "test_*.py" -v
```
测试 stub 了 Flask 和 SQLite,因此 `test_user_lookup.py` 可以在普通的 Python 3
环境下运行,无需数据库或任何第三方 package 存在。
## ✅ 核心要点
| 漏洞类别 | GHAS 功能 | 能捕获的内容 |
|---------------------|--------------|-----------------|
| 不安全代码 (SQLi) | CodeQL code scanning | Tainted 数据流,source → sink |
| 硬编码 secrets | Secret scanning + push protection | 符合服务商模式的凭证,在 commit 时被拦截 |
| 脆弱依赖项 | Dependabot | 已知的 CVE,包含严重程度 + 分类信息 |
GHAS 对代码级和已知的供应链风险具有强大、直接的覆盖能力,并作为应对更难的人类判断风险的
系统性安全网。在 AI 编写代码份额不断增加的时代,正是这一自动化层
防止了速度演变成暴露风险。
## ⚙️ 复现此设置
此演示适用于在任何 repo 上启用了 GitHub Advanced Security 的情况。要复制它:
1. 在你的 repo 上**启用 GitHub Advanced Security** *(Settings → Advanced Security)*
2. **启用 CodeQL code scanning** — 并选择 **`security-extended` 查询套件**;
默认套件为了低噪音进行了调整,将*不会*标记场景 1 中的 SQL injection
3. **启用 secret scanning *和* push protection** — push protection 是在场景 2 中阻止
commit 的关键,而不是事后报警
4. **启用 Dependabot alerts 和安全更新** — 可选地添加一个
`.github/dependabot.yml` 来控制更新计划
然后添加脆弱的代码(或向 AI 助手索要此类代码),打开一个 pull request,并观察
警报出现在 PR 上。
## 📚 资源
- [GitHub Advanced Security 文档](https://docs.github.com/en/get-started/learning-about-github/about-github-advanced-security)
- [CodeQL 文档](https://codeql.github.com/docs/)
- [Secret Scanning 文档](https://docs.github.com/en/code-security/secret-scanning/about-secret-scanning)
- [Dependabot 文档](https://docs.github.com/en/code-security/dependabot)
- [GitHub Security Lab](https://securitylab.github.com/)标签:AI辅助编程, CISA项目, DevSecOps, DOE合作, 上游代理, 代码安全, 安全演练, 漏洞枚举, 逆向工具, 错误基检测, 静态代码分析