我的漏洞扫描器,把被测项目的源码写坏了

我的漏洞扫描器,把被测项目的源码写坏了

配套仓库:github.com/mabupt/open... 感谢各位查看并提出意见,劳烦各位star。

先说结论

我给自己的 Python 漏洞检测流水线加了"动态验证"------在 Docker 沙箱里真实触发被测代码的漏洞, 用双轨证据(Sink 调用记录 + Canary 污点)判定告警真假。跑通那天很爽:靶场上 15 条告警被实证确认。

第二天重跑,confirmed 从 15 掉到 2。

排查了半天,原因不是模型、不是规则、也不是我以为的"镜像变弱了"------ 是我自己的扫描器把被测项目的源码写坏了。

事故经过

被测靶场 pygoat 里有两个 lab,漏洞本身就是"把用户提交的内容写进源文件":

python 复制代码
# pygoat A9 lab(简化)------漏洞就是把用户输入写入 Python 源文件
def a9_lab(request):
    log_code = request.POST.get("log_code")
    with open("playground/A9/main.py", "w") as f:
        f.write(log_code)

动态验证的设计就是真实利用 这类漏洞:构造载荷 → 发请求 → 观察 Sink 是否被污染。 探针一跑,playground/A9/main.py 和 playground/A6/utility.py 就被我自己的载荷覆盖成了空内容。

接下来的连锁反应很隐蔽:

  1. 被写坏的文件属于 introduction.apis 模块 → 导入失败;
  2. Django 的 URLconf 只剩 7 条路由,其余回调退化成占位对象;
  3. 所有 Django 路由返回 500 → 探针拿不到任何 Canary 污点证据;
  4. 结果:Django 系候选 16 条全部 app_unreachable / retry_poc。

最讽刺的地方:这不是"检测失败",而是"检测成功得过了头"------工具确实证明了漏洞可利用, 代价是把被测代码本身当作攻击目标写坏了。

修复:副本挂载

根因很明确:探针是直接 bind mount 宿主工程目录进容器的,写操作直达真实文件。

修复方式是把"被测工程"以副本 形式挂进容器,并且保持相同的容器内路径:

python 复制代码
copy_dir = self._protected_copy(target)      # output/sandbox/protect_<hash>/
mounts.append(Mount("/workspace/<rel>", str(copy_dir), type="bind"))

有两个"顺手就能做错"的细节:

  • 副本创建失败时不能回退为挂载原目录 。我一开始的回退逻辑是 except: continue, 结果是"隔离静默失效"------探针照样写宿主。现在改为:副本建不出来就直接放弃这次探针, 宁可少做一次动态验证,也不冒险写坏用户工程。
  • 仓库外的目标同样要隔离 。我用 relative_to(workspace_root) 判断路径, 目标不在仓库内时抛 ValueError,而那个异常被 except: continue 吞掉了------ 也就是说,用户扫描自己仓库外的项目时,隔离是完全失效的 。现在统一约定: 仓库内挂 /workspace/<rel>,仓库外挂 /target,副本挂载逻辑三方共享。

验证方式很直接:跑完后看副本目录------A9/main.py、A6/utility.py 确实变成了 0 字节, 宿主工程的文件完好无损。

顺带修复:换环境即踩的三类坑

这次事故让我意识到:"在我机器上能跑"和"在别人机器上能跑"是两件事。于是做了一轮针对性复查:

  1. 换项目 → 路径约定三方不一致 :探针按宿主绝对路径找目标、沙箱挂 /workspace、 供给流程挂 /proj,三处各搞各的。统一为一套路径换算函数。
  2. 换环境 → 仓库外目标无隔离:见上一条,同一个根因。
  3. 换解释器 → 附加产物不应该让主流程陪葬 :用 python -m venv 建一个 零第三方依赖 的环境跑全流程------发现缺 jinja2 时,JSON 报告已经写好了, 却因为 HTML 渲染抛异常导致整个流程 exit 1。现在 HTML 降级为"只出 JSON + 告警", 并做了更彻底的验证:42 个模块全部可导入(第三方依赖均为延迟导入), Semgrep / CodeQL / pip-audit 走 PATH 照常工作, Qdrant / fastembed / Docker 缺失时逐级降级,全流程 exit 0。

值得记下来的四条经验

  1. 动态验证工具必须假定"被测代码会被破坏"。因为触发漏洞的后果就是破坏------ 哪怕破坏对象是它自己。隔离不是可选项。
  2. except: continue 是隔离类代码里最危险的写法。它把"隔离失败"变成了"静默不隔离", 比直接报错危险得多。
  3. "降级"要覆盖到最外层。附加产物(HTML 报告)失败不该让主产物(JSON)和整个流程陪葬。
  4. 换环境测试比加功能更值得投入。上面三个坑,没有一个能在"我自己机器上跑一遍"时暴露。

相关的完整加固记录见仓库 docs/HARDENING.md。 项目地址:github.com/mabupt/open...

相关推荐
这个DBA有点耶3 天前
MySQL字符集与排序规则深入:索引失效的隐蔽场景与排查方法
数据库·mysql·代码规范
咖啡八杯4 天前
常量与枚举设计规范:HttpStatus 自定义 601 警告码
java·架构·代码规范
这个DBA有点耶6 天前
从异步复制到MGR:MySQL复制机制的三层演进与选型框架
数据库·mysql·代码规范
kisshyshy6 天前
《从屎山到秩序:Vibe Coding 95 驾驭术全公开》
人工智能·代码规范·vibecoding
深圳老胡12 天前
STM32F407 控制 L6470 步进电机驱动 —— 控制过程简介
笔记·stm32·单片机·嵌入式硬件·代码规范
怕浪猫12 天前
ZCode 开源了来看看这是个什么东西
node.js·github·代码规范
Liaiyang6613 天前
# 自研 AST 容错初筛工具:横向评测 Django、PyTorch、TensorFlow 三大开源 Python 框架异常收容风险
python·测试工具·自动化·开源软件·代码规范·devops·代码复审
kisshyshy14 天前
从Props透传到自定义Hook:系统梳理React跨层级通信与逻辑复用
前端·架构·代码规范
Flynt15 天前
阿里开源的 AI 代码评审工具,我喂了 5 个坑,一个没漏
开源·ai编程·代码规范