Aditea19/Code-Security-Risk-Intelligence-Agent
GitHub: Aditea19/Code-Security-Risk-Intelligence-Agent
该项目是一款Python代码库自动化安全风险情报工具,通过AST可达性分析与LLM推理相结合来评估依赖漏洞的实际可利用性和风险评分。
Stars: 0 | Forks: 0
# 代码安全与风险情报 Agent 🛡️
### 针对 Python 仓库的自动化代码安全与风险情报 Agent
**代码安全与风险情报 Agent** 是一款先进的生产级安全分析 CLI 工具,旨在弥合静态代码扫描与实际可利用性之间的差距。
传统的依赖扫描器向开发团队输出大量 CVE 警报,其中大多数在应用代码中是无法触达的。该 Agent 通过结合**基于 AST 的确定性可达性分析**与**LLM 风险推理**,来计算每个依赖项漏洞的实际影响和被利用的可能性,从而解决了这一问题。
## 🏗️ 高层架构
该 Agent 采用**整洁架构**(Clean Architecture)模式构建,通过从 CLI 请求开始的顺序流水线编排器来路由执行过程。
```
graph TD
User([User CLI Scan request]) --> Scan[scan.py CLI Entrypoint]
Scan --> Orch[Pipeline Orchestrator]
subgraph Services & Parsers
Orch --> RM[Repository Manager]
Orch --> MP[Manifest Parser]
Orch --> AP[AST Code Parser]
end
subgraph Pipelines & Agents
Orch --> DepA[Dependency Intel Agent OSV.dev]
Orch --> ScanA[Security Scanner Agent Bandit + pip-audit]
Orch --> ReachA[Reachability Analysis Agent AST Caller Graph]
Orch --> ReasonA[Risk Reasoning LLM Agent]
Orch --> ReportA[Report Generator Agent Markdown + JSON]
end
ReportA --> Output[/Markdown + JSON Reports/]
```
## 🛠️ 技术栈
- **核心引擎**:Python 3.12
- **确定性检查器**:Bandit(AST SAST)、pip-audit(清单漏洞审计工具)
- **漏洞数据**:OSV.dev REST API
- **Git 提供程序**:GitPython
- **LLM 推理引擎**:Gemini 1.5 Flash / Gemini 3.1 Flash-Lite(REST API v1beta JSON schema 执行,可在 `.env` 中配置)
- **数据模式**:Pydantic v2
- **测试套件**:pytest
## 📦 安装与设置
### 前置条件
- **Python 3.12+**
- **Git**(已安装在系统 PATH 中)
### 本地安装
1. 克隆或将项目目录复制到您的本地环境。
2. 初始化虚拟环境并安装依赖项:
python -m venv venv
venv\Scripts\activate.bat # 在 Linux/macOS 上使用:source venv/bin/activate
pip install -r requirements.txt
3. 在项目根目录下的 `.env` 文件中配置环境变量:
GEMINI_API_KEY=your_gemini_api_key_here
LLM_MODEL=gemini-flash-lite-latest
LOG_LEVEL=INFO
## 🚀 使用指南
要直接从命令行扫描公开的 GitHub 仓库:
```
python scan.py https://github.com/bottlepy/bottle
```
要针对特定的分支或发布标签(推荐用于分析代码库的较早的、存在漏洞的版本):
```
python scan.py https://github.com/psf/requests --branch v2.25.0
```
生成的 Markdown 报告和原始 JSON 数据将直接写入 `reports/` 文件夹。
## 🧠 风险评分公式
该 Agent 使用优先考虑确定性证据的结构化公式来计算最终威胁等级:
$$\text{Risk Score} = 0.35 \times \text{CVSS} + 0.30 \times \text{Reachability} + 0.20 \times \text{Exposure} + 0.15 \times \text{Business Impact}$$
### 评分定义:
1. **CVSS**:漏洞基础评级(0.0 到 10.0)。如果缺失,则默认为 5.0。
2. **Reachability**(可达性):通过 AST 调用链以编程方式检查:
- `Possibly Reachable`(可能可达)= 0.8(已确认指向包边界的直接或传递调用链)
- `Possibly Reachable (No Active Chain)`(可能可达 - 无活跃链)= 0.6(包已被导入并使用,但没有活跃的入口点映射到它)
- `Not Reachable`(不可达)= 0.1(包在代码库中的任何地方都未被导入)
3. **Exposure**(暴露面):
- `Possibly Reachable`(可能可达)= 0.5
- `Not Reachable`(不可达)= 0.1
4. **Business Impact**(业务影响):由 Gemini 推理 Agent 根据漏洞利用上下文(例如:远程代码执行 vs. 简单的拒绝服务)评估的利用影响(0.0 到 1.0)。
* **Reachability 追踪**:对于每个存在漏洞的依赖项,该 Agent 会通过 AST 解析定位其导入,找到引用它们的每个函数,并静态追踪是否有任何调用链能够到达公共入口点 —— 即应用/测试入口函数、路由或 CLI 命令。
## 📊 系统评估结果
该 Agent 的能力已在 **15 个公开的 Python 仓库**上进行了验证,以衡量漏洞检测的准确性。以下是为每个仓库发现的实际漏洞数量:
| 仓库名称 | 扫描目标 / 版本 | 发现的依赖项漏洞 | 报告文件链接 |
|-----------------|-----------------------|--------------------------------------|------------------|
| **[requests](https://github.com/psf/requests)** | 标签 `v2.25.0` | **17** | [查看报告](reports/requests.md) |
| **[Pillow](https://github.com/python-pillow/Pillow)** | 标签 `8.0.0` | **15** | [查看报告](reports/Pillow.md) |
| **[cookiecutter](https://github.com/cookiecutter/cookiecutter)** | 标签 `v1.7.2` | **15** | [查看报告](reports/cookiecutter.md) |
| **[paramiko](https://github.com/paramiko/paramiko)** | 标签 `v2.4.0` | **14** | [查看报告](reports/paramiko.md) |
| **[flask](https://github.com/pallets/flask)** | 标签 `1.1.2` | **10** | [查看报告](reports/flask.md) |
| **[urllib3](https://github.com/urllib3/urllib3)** | 标签 `1.26.4` | **1** | [查看报告](reports/urllib3.md) |
| **[bottle](https://github.com/bottlepy/bottle)** | 标签 `0.12.19` | **1** | [查看报告](reports/bottle.md) |
| **[oyaml](https://github.com/wimglenn/oyaml)** | 最新 `master` 分支 | **0** | [查看报告](reports/oyaml.md) |
| **[werkzeug](https://github.com/pallets/werkzeug)** | 最新 `main` 分支 | **0** | [查看报告](reports/werkzeug.md) |
| **[click](https://github.com/pallets/click)** | 最新 `main` 分支 | **0** | [查看报告](reports/click.md) |
| **[starlette](https://github.com/encode/starlette)** | 标签 `0.14.1` | **21** | [查看报告](reports/starlette.md) |
| **[lxml](https://github.com/lxml/lxml)** | 最新 `master` 分支 | **0** | [查看报告](reports/lxml.md) |
| **[pluggy](https://github.com/pytest-dev/pluggy)** | 最新 `main` 分支 | **0** | [查看报告](reports/pluggy.md) |
| **[jinja](https://github.com/pallets/jinja)** | 最新 `main` 分支 | **0** | [查看报告](reports/jinja.md) |
| **[typer](https://github.com/fastapi/typer)** | 最新 `master` 分支 | **0** | [查看报告](reports/typer.md) |
## 🛠️ 发现并修复的故障模式
1. **占位符推理输出:** 早期报告显示的是通用的填充文本(*"Vulnerability assessed by reasoning agent"*),而不是真实的 LLM 推理。
* *实际修复:* 解决了 LLM 响应的 JSON schema 解析问题,并将来自推理 Agent 的 `RiskAssessment` 对象直接集成到了 Markdown 报告生成器模板中。
2. **矛盾的可达性判定:** 即使可达性追踪根本没有找到调用链,一些表中的发现仍被标记为 "Possibly Reachable"(可能可达),反之亦然。
* *实际修复:* 统一了可达性 Agent 的发现,确保对于任何流向包边界的已验证调用路径一致地显示为 `"Possibly Reachable"`,从而确保推理 Agent 的 429 速率限制/503 服务不可用回退机制与 AST 可达性输出在数学和逻辑上保持一致。
3. **通用的、无差异的风险评分:** 业务影响和利用可能性在不相关的漏洞中落在了几乎相同的值上,因为 prompt 给了 LLM 一个没有落地指令的数字范围。
* *实际修复:* 在推理 prompt 中添加了明确的、基于证据的评分规则和防重复指令。
4. **CVSS 向量解析错误:** Google 的 OSV API 在其 `score` 字段中以字符串形式返回 CVSS 基础向量,导致浮点转换出现 `ValueError` 并回退到硬编码的 `5.0`。
* *实际修复:* 在 `reasoning_agent/agent.py` 中实现了原生的 CVSS v3 数学解析引擎,以在本地计算精确的十进制 CVSS 分数。
5. **重复的代表性调用路径:** AST 解析器匹配了同一个入口点函数内的多个调用点,导致报告多次列出相同的代表性路径。
* *实际修复:* 在报告 Agent 中基于唯一的入口点实现了去重过滤器,并优先考虑生产源码调用路径(`src/`、`app/`)而不是测试文件。
## ⚠️ 局限性
1. **AST 解析限制**:标准的静态 AST 解析无法检测动态调用(例如 `getattr(module, func_name)()`)、`eval()` 或在动态执行的字符串中导入的依赖项。
2. **生态系统限制**:目前仅支持 Python 代码库和生态系统(`requirements.txt`、`pyproject.toml`、`Pipfile`、`poetry.lock`)。
3. **可达性发现是基于证据的,而非证明**:"Not Reachable"(不可达)表示未找到路径,而不是证明绝对不可能存在路径。
标签:Python, 代码安全, 大模型驱动, 安全规则引擎, 无后门, 漏洞可达性分析, 漏洞枚举, 静态应用安全测试