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 生成代码中的漏洞。** [![GitHub Advanced Security](https://img.shields.io/badge/GitHub-Advanced%20Security-blue?logo=github&logoColor=white)](https://github.com/features/security) [![CodeQL](https://img.shields.io/badge/CodeQL-Enabled-brightgreen?logo=github)](https://codeql.github.com/) [![Secret Scanning](https://img.shields.io/badge/Secret%20Scanning-Active-orange?logo=github)](https://docs.github.com/en/code-security/secret-scanning) [![Dependabot](https://img.shields.io/badge/Dependabot-Enabled-yellow?logo=dependabot)](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合作, 上游代理, 代码安全, 安全演练, 漏洞枚举, 逆向工具, 错误基检测, 静态代码分析