arkanzasfeziii/Race-Condition-Vulnerability-Scanner

GitHub: arkanzasfeziii/Race-Condition-Vulnerability-Scanner

一款结合静态AST分析与动态多线程压力测试的Python竞态条件漏洞扫描器,用于自动检测代码中的TOCTOU缺陷、原子性违规及各类并发同步隐患。

Stars: 0 | Forks: 0

# 竞态条件漏洞扫描器 [![Python](https://img.shields.io/badge/python-3.8%2B-blue.svg)](https://www.python.org/) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) [![CI](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/127c01e3b3232419.svg)](https://github.com/arkanzasfeziii/Race-Condition-Vulnerability-Scanner/actions/workflows/lint.yml) [![Threading](https://img.shields.io/badge/detection-multi--threaded-orange.svg)]() 一款针对 Python 代码库的专业静态与动态竞态条件漏洞扫描器。通过同步的多线程请求突发检测 TOCTOU 缺陷、Read-Modify-Write 原子性违规、未同步的共享资源访问、数据库并发问题以及 asyncio 竞态。 ## 什么是竞态条件? **竞态条件**(Race Condition)是指程序的执行结果取决于并发操作的相对执行时间。其中影响最大的两类是: ### TOCTOU (Time-of-Check to Time-of-Use) 资源在独立的、非原子的步骤中被检查(例如 `os.path.exists(f)`),然后被使用(例如 `open(f)`)。攻击者或并发线程可以在检查与使用之间的时间窗口内修改该资源。 **现实世界中的影响:** - 通过符号链接攻击实现权限提升 - 支付系统中的双重消费(检查余额,然后扣款 —— 两个线程都通过了检查) - 优惠券绕过:两个并发请求在任何一个将其标记为已使用之前,都验证了同一张一次性优惠券 ### Read-Modify-Write (RMW) 原子性违规 像 `counter += 1` 这样的操作并不是原子性的。它们会展开为 `READ counter`、`ADD 1`、`WRITE counter` —— 这三个独立的步骤可能会在线程之间发生交错,从而导致更新丢失。 ## 检测技术 | 技术 | 描述 | |-----------|-------------| | **静态 AST 分析** | 使用 `ast` 解析 Python 源代码,以查找 TOCTOU 模式、针对共享变量的增强赋值以及锁对象跟踪 | | **动态压力测试** | 针对提取的函数生成 N 个并发线程/进程,并比较输出的哈希值以检测不一致性 | | **同步请求突发** | 通过随机的微秒级延迟同时启动所有 worker,以扩大竞态窗口 | | **响应差异分析** | 将所有结果序列化为 JSON 并比较 SHA-256 哈希值 —— 任何差异都标志着存在真实的竞态 | | **数据库竞态探测** | 创建内存中的 SQLite 测试环境,并运行并发的 Read-Modify-Write 事务 | ## 功能 - 检测 **9 种竞态条件类型**:TOCTOU、Read-Modify-Write、未同步访问、文件竞态、信号处理程序竞态、复合操作、全局变量、数据库竞态、asyncio 竞态 - **双重分析模式**:快速的纯静态分析或静态与动态结合分析 - 带有可配置阈值的**置信度评分** - 为每个检测到的问题生成 **ASCII 时序图** - 用于 CI/CD 流水线集成的 **JSON 输出** - 用于自定义阈值和忽略模式的 **YAML 配置** - 用于扩展检测逻辑的**插件系统** - 在动态测试中绕过 Python GIL 的**多进程支持** - 带有按严重程度分类结果的**彩色终端输出** ## 安装 ``` git clone https://github.com/arkanzasfeziii/Race-Condition-Vulnerability-Scanner.git cd Race-Condition-Vulnerability-Scanner pip install -r requirements.txt ``` 可选依赖: ``` pip install pyyaml colorama hypothesis ``` ## 用法 ``` # 扫描单个文件 python race_detector.py --file myapp.py # 扫描项目目录 python race_detector.py --path ./src --threads 16 --iterations 1000 # 仅静态分析(快速,无 subprocess spawning) python race_detector.py --path . --static-only --ignore "test,venv" # 用于 CI/CD 的 JSON 输出 python race_detector.py --file app.py --output json > races.json # 使用 config 文件 python race_detector.py --path ./src --config example/detector.yaml # 加载自定义 plugins python race_detector.py --path . --plugin-dir ./plugins # 运行内置自测 python race_detector.py --self-test --verbose ``` ### CLI 参考 | 标志 | 默认值 | 描述 | |------|---------|-------------| | `--file FILE` | — | 要扫描的单个 Python 文件 | | `--path DIR` | — | 要递归扫描的目录 | | `--snippet CODE` | — | 要分析的内联代码字符串 | | `--threads N` | 8 | 用于动态测试的并发 worker | | `--iterations N` | 1000 | 每个候选函数的测试迭代次数 | | `--static-only` | false | 跳过动态执行 | | `--ignore PATTERNS` | — | 要跳过的路径子字符串(以逗号分隔) | | `--config FILE` | — | YAML 配置文件(参见 `example/detector.yaml`) | | `--plugin-dir DIR` | — | 包含插件 `.py` 文件的目录 | | `--output text\|json` | text | 报告格式 | | `--verbose / -v` | false | 调试日志记录 | **退出代码:** `0` = 未发现竞态,`1` = 检测到竞态,`2` = 致命错误,`130` = 被中断。 ## 示例输出 ``` ================================================================================ RACE CONDITION DETECTION REPORT by arkanzas.feziii ================================================================================ Scan Statistics: Files Analyzed: 1 Lines of Code: 42 Race Conditions Found: 2 Min Confidence: 70% Severity Breakdown: HIGH : 1 MEDIUM : 1 [1] [HIGH] HIGH - Read-Modify-Write Atomicity Violation -------------------------------------------------------------------------------- File: counter.py Line: 8 Method: STATIC Confidence: 92% Variable: counter Description: Non-atomic read-modify-write on 'counter'. Compound operations like '+=' are not atomic and lose updates in concurrent execution. Visualization: Thread A Thread B | Read counter | Read counter | (counter=10) | (counter=10) | Modify (+1) | Modify (+1) | Write counter=11 | Write counter=11 Lost update! Final value: 11 (should be 12) Recommended Fix: Use threading.Lock() for compound operations, or use atomic types from multiprocessing.Value/Array if using processes. ``` ## 插件系统 将一个 `.py` 文件放入 `plugins/` 目录(或通过 `--plugin-dir` 指定的自定义目录)。每个插件必须继承 `PluginInterface` 并实现 `analyze()` 方法: ``` from race_detector import PluginInterface, RaceCondition, RaceType, Severity, DetectorConfig class MyCustomDetector(PluginInterface): def analyze(self, code: str, file_path: str, config: DetectorConfig): races = [] # ... your detection logic using ast or regex ... return races ``` 有关完整的接口约定,请参阅 `plugins/README.md`。 ## 配置 复制 `example/detector.yaml` 并进行自定义: ``` min_confidence: 0.75 # Only report findings above this threshold max_threads: 16 # Dynamic test concurrency iterations: 1000 # Iterations per candidate function timeout_per_test: 10 # Seconds before killing a test subprocess ignore_patterns: - "test" - "__pycache__" - ".venv" enable_multiprocessing: true enable_asyncio_detection: true enable_db_detection: true ``` ## CI/CD 集成 ``` # .github/workflows/race-check.yml - name: Race condition scan run: | python race_detector.py --path . --output json --static-only > races.json if [ $? -eq 1 ]; then echo "Race conditions detected!"; exit 1; fi ``` ## 检测到的竞态条件类型 | 类型 | 描述 | |------|-------------| | `TOCTOU` | 文件/资源在使用前进行了检查,且没有原子性保证 | | `READ_MODIFY_WRITE` | 在共享状态上执行非原子的复合操作 (+=, -= 等) | | `UNSYNCHRONIZED_ACCESS` | 在没有锁保护的情况下写入共享变量 | | `FILE_RACE` | 在并发环境中进行文件操作 | | `SIGNAL_RACE` | 在多线程程序中注册信号处理程序 | | `COMPOUND_OPERATION` | 通过不一致的输出动态确认的竞态 | | `GLOBAL_VARIABLE` | 使用全局变量的多线程且没有 Lock 对象 | | `DATABASE_RACE` | 没有事务锁的并发数据库操作 | | `ASYNCIO_RACE` | 多个 async 函数在没有 asyncio.Lock 的情况下共享状态 | | `TEMPFILE_RACE` | 在并发环境中使用带 delete=False 的 NamedTemporaryFile | ## 作者 **arkanzas.feziii** — MIT License 有关负责任的披露,请参阅 [SECURITY.md](SECURITY.md);有关贡献指南,请参阅 [CONTRIBUTING.md](CONTRIBUTING.md)。
标签:Python, 加密, 并发安全, 无后门, 漏洞扫描器, 竞态条件, 计算机取证, 逆向工具, 错误基检测, 静态代码分析