AI 写的 Python 代码的安全审查 · 第 04 题
第 4 课:像攻击者一样复查
测试全绿和 9/9 的重放只是地板。重放第二个皮肤、跑一遍静态扫描并记下它漏了什么、攻击一处套件从没试过的地方,并写下还有什么没审查。
在用 Agent 做题?一句话开始整门课程:
Read https://flypython.com/skills/flypython/SKILL.md and start the FlyPython course `secure-ai-generated-code`.AI 写的 Python 代码的安全审查 · 第 04 题
测试全绿和 9/9 的重放只是地板。重放第二个皮肤、跑一遍静态扫描并记下它漏了什么、攻击一处套件从没试过的地方,并写下还有什么没审查。
在用 Agent 做题?一句话开始整门课程:
Read https://flypython.com/skills/flypython/SKILL.md and start the FlyPython course `secure-ai-generated-code`.两个套件都通过、两个皮肤的重放全部被挡住,你手握一份书面记录:审查了 什么、扫描器抓到和没抓到什么、还有什么没人审查过。
blocked=9/9 很容易被过度解读。它的意思是九个特定攻击被挡住了。真正的
攻击者会试第十个。安全审查就是追问「测试没试过什么」的习惯——并把答案
写下来,而不是想当然。
亲自跑维护者那一对命令和两次重放:
python verify.py starter
python verify.py solution
python starter/attack_replay.py scenario/team-notes
python starter/attack_replay.py scenario/clinic-notes
套件只重放 team-notes。clinic-notes 用的是不同的 payload——
x' OR 1=1 --、注入到 owner 而不是查询里、scans/../../secrets.txt、
空密钥。如果你的修复都是机制,它不做任何改动就会打印 blocked=8/8。如果
没有,说明你有一处修复是过滤器。
然后做套件做不了的审查:
跑静态扫描,再读它漏了什么。 如果你有 Ruff(仓库的开发依赖里有 它),对你的修复跑它的 flake8-bandit 规则:
ruff check --isolated --select S starter/notes_app.py
你的修复应该什么都不报。作为对照,在原始 starter 上 Ruff 0.16.10 报告
S608(由字符串拼出的 SQL)、S324(MD5,两处)和 S301(pickle.loads)
——对路径拼接和 "dev-secret-change-me" 兜底值什么都不报。如果你提交过
基线,对它跑同一条命令就能亲眼看到。扫描器是能抓住已知模式的快速初筛;
它不是审查。
攻击一处套件从没试过的地方。 挑一个:带 Unicode 大小写的搜索
(É 与 é)、一个是目录的附件名、一个签名有效但内容是 JSON 列表的
会话 token、一个 10 000 字符长的密码。先预测,再运行,记下结果。
读 diff 里删掉了什么。 用 git diff 对比 starter 与你的基线。确认
pickle 和 md5 都没了,也没有 except Exception 吞掉
SecurityError。
为这次改动写安全证据记录:
attacks.json 里的攻击。运行 python verify.py。starter 套件通过后本检查点的码就会打印;上面那
一对维护者命令都必须是绿的,这道门才名副其实。不看材料能回答即算通过:
clinic-notes 不做改动就通过了吗?如果没有,哪处修复是过滤器?两次全绿运行、两次重放输出、扫描输出,以及你的三行证据记录。
提示
starter 和 solution 双双通过——维护者那一对命令 verify.py starter / verify.py solution 都必须是绿的,你的 starter 套件通过后 python verify.py 打印本检查点的码。
在这个 starter 上,ruff 的 S 规则标出了 f-string SQL、MD5 和 pickle.loads——对路径拼接和兜底密钥一言不发。把干净的扫描结果当作证据中的一行。
你有一份安全证据记录——已验证 / 未验证 / 已知局限——点名了没人审查过的部分。
提交
提交 python verify.py 为本检查点打印的 8 位认领码。自报关卡要先完成课后问题,再运行 python verify.py --attest l04。
只有记录积分和徽章才需要账号——读题和解题永远免费。
把这题交给它(悬停出现复制按钮)——解题、验证、提交全程自动:
请完成 FlyPython 挑战课程「AI 写的 Python 代码的安全审查」(course id course-secure-code)的检查点 l04。
机读简报:https://flypython.com/api/challenges/secure-ai-generated-code
打开课程文件夹,先读 TASK.md——它就是契约。
规则:最小变更、不新增依赖、绝不修改 tests/ 或 solution/。
用 python verify.py 检查 starter/;自报关卡先让我回答课后问题,再运行 --attest ID 取得码。
目标:只做检查点 l04 这一道题,完成后立即提交。用你Agent 页生成的令牌(环境变量 FLYPYTHON_TOKEN),它可以直接记录结果:
curl -X POST https://flypython.com/api/claims \
-H "Authorization: Bearer $FLYPYTHON_TOKEN" \
-H "Content-Type: application/json" \
-d '{"claims":[{"course":"secure-ai-generated-code","checkpoint":"l04","code":"<8-char code>"}]}'或一次性安装完整的 FlyPython Agent Skill,连粘贴都省了。
解题在你的机器上运行——Agent 通过 /api/challenges/secure-ai-generated-code/files 自己取回课程文件,你无需手动下载。想直接读源码?在 GitHub 上查看文件夹 ↗