feat(agent): 增加漏洞文件统计功能并优化agent提示词

- 在AgentTask模型中添加files_with_findings字段统计有漏洞发现的文件数
- 更新前后端接口和界面展示漏洞文件统计
- 优化各Agent的系统提示词,移除冗余内容并增强工具使用约束
- 增加LLM的max_tokens至8192避免截断
- 添加生产环境docker-compose配置和更新README部署说明
This commit is contained in:
lintsinghua 2025-12-16 22:08:45 +08:00
parent cd79242b3e
commit 6c080fc5d6
14 changed files with 453 additions and 437 deletions

View File

@ -158,47 +158,89 @@ DeepAudit/
---
## 🚀 快速开始 (Docker)
## 🚀 快速开始
### 1. 启动项目
### 方式一:一行命令部署(推荐)
复制一份 `backend/env.example``backend/.env`,并按需配置 LLM API Key。
然后执行以下命令一键启动:
使用预构建的 Docker 镜像,无需克隆代码,一行命令即可启动:
```bash
# 1. 准备配置文件
cp backend/env.example backend/.env
# 2. 构建沙箱镜像 (首次运行必须)
cd docker/sandbox && chmod +x build.sh && ./build.sh && cd ../..
# 3. 启动服务
docker compose up -d
# 设置你的 LLM API Key然后一键部署
LLM_API_KEY=your-api-key-here \
curl -fsSL https://raw.githubusercontent.com/lintsinghua/DeepAudit/main/docker-compose.prod.yml | docker compose -f - up -d
```
> 🎉 **启动成功!** 访问 http://localhost:3000 开始体验。
<details>
<summary>💡 配置说明(点击展开)</summary>
**环境变量配置:**
| 变量 | 说明 | 默认值 |
|------|------|--------|
| `LLM_API_KEY` | LLM API 密钥(必填) | - |
| `LLM_PROVIDER` | LLM 提供商 | `openai` |
| `LLM_MODEL` | 模型名称 | `gpt-4o` |
| `LLM_BASE_URL` | API 地址(用于中转站或本地模型) | - |
**使用其他模型示例:**
```bash
# 使用 DeepSeek
LLM_API_KEY=sk-xxx LLM_PROVIDER=deepseek LLM_MODEL=deepseek-chat \
curl -fsSL https://raw.githubusercontent.com/lintsinghua/DeepAudit/main/docker-compose.prod.yml | docker compose -f - up -d
# 使用 Claude
LLM_API_KEY=sk-ant-xxx LLM_PROVIDER=anthropic LLM_MODEL=claude-sonnet-4-20250514 \
curl -fsSL https://raw.githubusercontent.com/lintsinghua/DeepAudit/main/docker-compose.prod.yml | docker compose -f - up -d
# 使用本地 Ollama
LLM_PROVIDER=ollama LLM_MODEL=qwen2.5:14b LLM_BASE_URL=http://host.docker.internal:11434 \
curl -fsSL https://raw.githubusercontent.com/lintsinghua/DeepAudit/main/docker-compose.prod.yml | docker compose -f - up -d
```
</details>
---
## 🔧 源码启动指南
### 方式二:克隆代码部署
适合需要自定义配置或二次开发的用户:
```bash
# 1. 克隆项目
git clone https://github.com/lintsinghua/DeepAudit.git && cd DeepAudit
# 2. 配置环境变量
cp backend/env.example backend/.env
# 编辑 backend/.env 填入你的 LLM API Key
# 3. 一键启动
docker compose up -d
```
> 首次启动会自动构建沙箱镜像,可能需要几分钟。
---
## 🔧 源码开发指南
适合开发者进行二次开发调试。
### 环境要求
- Python 3.10+
- Node.js 18+
- PostgreSQL 14+
- Python 3.11+
- Node.js 20+
- PostgreSQL 15+
- Docker (用于沙箱)
### 1. 后端启动
```bash
cd backend
# 激活虚拟环境 (推荐 uv/poetry)
source .venv/bin/activate
# 安装依赖
pip install -r requirements.txt
# 使用 uv 管理环境(推荐)
uv sync
source .venv/bin/activate
# 启动 API 服务
uvicorn app.main:app --reload
@ -208,16 +250,16 @@ uvicorn app.main:app --reload
```bash
cd frontend
npm install
npm run dev
pnpm install
pnpm dev
```
### 3. 沙箱环境
开发模式下,仍需通过 Docker 启动沙箱服务。
开发模式下需要本地 Docker 拉取沙箱镜像:
```bash
cd docker/sandbox
./build.sh
docker pull ghcr.io/lintsinghua/deepaudit-sandbox:latest
```
---

View File

@ -0,0 +1,35 @@
"""Add files_with_findings column to agent_tasks
Revision ID: 008_add_files_with_findings
Revises: 4c280754c680
Create Date: 2025-12-16
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '008_add_files_with_findings'
down_revision = '4c280754c680'
branch_labels = None
depends_on = None
def upgrade() -> None:
# Add files_with_findings column to agent_tasks table (idempotent)
conn = op.get_bind()
inspector = sa.inspect(conn)
columns = [col['name'] for col in inspector.get_columns('agent_tasks')]
if 'files_with_findings' not in columns:
op.add_column(
'agent_tasks',
sa.Column('files_with_findings', sa.Integer(), nullable=True, default=0)
)
# Set default value for existing rows
op.execute("UPDATE agent_tasks SET files_with_findings = 0 WHERE files_with_findings IS NULL")
def downgrade() -> None:
op.drop_column('agent_tasks', 'files_with_findings')

View File

@ -445,14 +445,18 @@ async def _execute_agent_task(task_id: str):
task.tool_calls_count = result.tool_calls
task.tokens_used = result.tokens_used
# 🔥 统计分析的文件数量(从 findings 中提取唯一文件)
analyzed_file_set = set()
# 🔥 统计文件数量
# analyzed_files = 实际扫描过的文件数(任务完成时等于 total_files
# files_with_findings = 有漏洞发现的唯一文件数
task.analyzed_files = task.total_files # Agent 扫描了所有符合条件的文件
files_with_findings_set = set()
for f in findings:
if isinstance(f, dict):
file_path = f.get("file_path") or f.get("file") or f.get("location", "").split(":")[0]
if file_path:
analyzed_file_set.add(file_path)
task.analyzed_files = len(analyzed_file_set) if analyzed_file_set else task.total_files
files_with_findings_set.add(file_path)
task.files_with_findings = len(files_with_findings_set)
# 统计严重程度和验证状态
verified_count = 0

View File

@ -89,7 +89,8 @@ class AgentTask(Base):
# 进度统计
total_files = Column(Integer, default=0)
indexed_files = Column(Integer, default=0)
analyzed_files = Column(Integer, default=0)
analyzed_files = Column(Integer, default=0) # 实际扫描过的文件数
files_with_findings = Column(Integer, default=0) # 有漏洞发现的文件数
total_chunks = Column(Integer, default=0) # 代码块总数
# Agent 统计

View File

@ -85,15 +85,15 @@ ANALYSIS_SYSTEM_PROMPT = """你是 DeepAudit 的漏洞分析 Agent一个**自
- **dataflow_analysis**: 数据流追踪
参数: source_code (str), variable_name (str)
### 辅助工具
- **read_file**: 读取文件内容验证发现
### 辅助工具RAG 优先!)
- **rag_query**: **🔥 首选** 语义搜索代码理解业务逻辑
参数: query (str), top_k (int)
- **security_search**: **🔥 首选** 安全相关搜索
参数: query (str)
- **read_file**: 读取文件内容
参数: file_path (str), start_line (int), end_line (int)
- **list_files**: 列出目录文件
参数: directory (str), pattern (str)
- **search_code**: 代码关键字搜索
参数: keyword (str), max_results (int)
- **query_security_knowledge**: 查询安全知识库
- **get_vulnerability_knowledge**: 获取漏洞知识
- **list_files**: 仅列出目录严禁遍历
- **search_code**: 仅查找常量严禁通用搜索
## 📋 推荐分析流程(严格按此执行!)
@ -193,6 +193,26 @@ Final Answer: [JSON 格式的漏洞报告]
3. **上下文分析** - 看到可疑代码要读取上下文理解完整逻辑
4. **自主判断** - 不要机械相信工具输出要用你的专业知识判断
## ⚠️ 关键约束 - 必须遵守!
1. **禁止直接输出 Final Answer** - 你必须先调用工具来分析代码
2. **至少调用两个工具** - 使用 smart_scan/semgrep_scan 进行扫描然后用 read_file 查看代码
3. **没有工具调用的分析无效** - 不允许仅凭推测直接报告漏洞
4. ** Action Final Answer** - 必须先执行工具获取 Observation再输出最终结论
错误示例禁止
```
Thought: 根据项目信息可能存在安全问题
Final Answer: {...} 没有调用任何工具
```
正确示例必须
```
Thought: 我需要先使用智能扫描工具对项目进行全面分析
Action: smart_scan
Action Input: {"scan_type": "security", "max_files": 50}
```
然后等待 Observation再继续深入分析或输出 Final Answer
现在开始你的安全分析首先使用外部工具进行全面扫描"""
@ -402,7 +422,7 @@ class AnalysisAgent(BaseAgent):
## 可用工具
{self.get_tools_description()}
请开始你的安全分析首先读取高风险区域的文件然后分析其中的安全问题"""
请开始你的安全分析首先读取高风险区域的文件然后**立即**分析其中的安全问题输出 Action"""
# 🔥 记录工作开始
self.record_work("开始安全漏洞分析")
@ -437,7 +457,7 @@ class AnalysisAgent(BaseAgent):
llm_output, tokens_this_round = await self.stream_llm_call(
self._conversation_history,
temperature=0.1,
max_tokens=4096,
max_tokens=8192,
)
except asyncio.CancelledError:
logger.info(f"[{self.name}] LLM call cancelled")
@ -594,7 +614,7 @@ Final Answer: {{"findings": [...], "summary": "..."}}"""
await self.emit_llm_decision("继续分析", "LLM 需要更多分析")
self._conversation_history.append({
"role": "user",
"content": "请继续分析。选择一个工具执行,或者如果分析完成,输出 Final Answer 汇总所有发现。",
"content": "请继续分析。你输出了 Thought 但没有输出 Action。请**立即**选择一个工具执行,或者如果分析完成,输出 Final Answer 汇总所有发现。",
})
# 🔥 如果循环结束但没有发现,强制 LLM 总结

View File

@ -51,7 +51,7 @@ class AgentConfig:
# LLM 配置
model: Optional[str] = None
temperature: float = 0.1
max_tokens: int = 4096
max_tokens: int = 8192
# 执行限制
max_iterations: int = 20

View File

@ -242,7 +242,7 @@ class OrchestratorAgent(BaseAgent):
llm_output, tokens_this_round = await self.stream_llm_call(
self._conversation_history,
temperature=0.1,
max_tokens=4096, # 🔥 增加到 4096,避免截断
max_tokens=8192, # 🔥 增加到 8192,避免截断
)
except asyncio.CancelledError:
logger.info(f"[{self.name}] LLM call cancelled")
@ -678,21 +678,16 @@ Action Input: {{"参数": "值"}}
pass
raise asyncio.CancelledError("任务已取消")
try:
# 🔥 移除 asyncio.shield(),让取消信号可以直接传播
# 使用较短的超时来更频繁地检查取消状态
return await asyncio.wait_for(
run_task,
timeout=0.5 # 🔥 每0.5秒检查一次取消状态
)
except asyncio.TimeoutError:
continue
except asyncio.CancelledError:
# 🔥 捕获取消异常确保子Agent也被取消
logger.info(f"[{self.name}] Sub-agent {agent_name} received cancel signal")
if hasattr(agent, 'cancel'):
agent.cancel()
raise
# Use asyncio.wait to poll without cancelling the task
done, pending = await asyncio.wait(
[run_task],
timeout=0.5,
return_when=asyncio.FIRST_COMPLETED
)
if run_task in done:
return run_task.result()
# If not done, continue loop
continue
return await run_task
except asyncio.CancelledError:

View File

@ -19,11 +19,146 @@ from dataclasses import dataclass
from .base import BaseAgent, AgentConfig, AgentResult, AgentType, AgentPattern
from ..json_parser import AgentJsonParser
from ..prompts import RECON_SYSTEM_PROMPT, TOOL_USAGE_GUIDE
from ..prompts import TOOL_USAGE_GUIDE
logger = logging.getLogger(__name__)
RECON_SYSTEM_PROMPT = """你是 DeepAudit 的侦察 Agent负责收集和分析项目信息。
## 你的职责
作为侦察层你负责
1. 分析项目结构和技术栈
2. 识别关键入口点
3. 发现配置文件和敏感区域
4. **推荐需要使用的外部安全工具**
5. 提供初步风险评估
## 侦察目标
### 1. 技术栈识别(用于选择外部工具)
- 编程语言和版本
- Web框架Django, Flask, FastAPI, Express等
- 数据库类型
- 前端框架
- **根据技术栈推荐外部工具**
- Python项目 bandit_scan, safety_scan
- Node.js项目 npm_audit
- 所有项目 semgrep_scan, gitleaks_scan
- 大型项目 kunlun_scan, osv_scan
### 2. 入口点发现
- HTTP路由和API端点
- Websocket处理
- 定时任务和后台作业
- 消息队列消费者
### 3. 敏感区域定位
- 认证和授权代码
- 数据库操作
- 文件处理
- 外部服务调用
### 4. 配置分析
- 安全配置
- 调试设置
- 密钥管理
## 工作方式
每一步你需要输出
```
Thought: [分析当前情况思考需要收集什么信息]
Action: [工具名称]
Action Input: {"参数1": "值1"}
```
当你完成信息收集后输出
```
Thought: [总结收集到的所有信息]
Final Answer: [JSON 格式的结果]
```
## 输出格式
```
Final Answer: {
"project_structure": {...},
"tech_stack": {
"languages": [...],
"frameworks": [...],
"databases": [...]
},
"recommended_tools": {
"must_use": ["semgrep_scan", "gitleaks_scan", ...],
"recommended": ["kunlun_scan", ...],
"reason": "基于项目技术栈的推荐理由"
},
"entry_points": [
{"type": "...", "file": "...", "line": ..., "method": "..."}
],
"high_risk_areas": [
"文件路径:行号 - 风险描述"
],
"initial_findings": [
{"title": "...", "file_path": "...", "line_start": ..., "description": "..."}
],
"summary": "项目侦察总结"
}
```
## ⚠️ 重要输出要求
### recommended_tools 格式要求
**必须**根据项目技术栈推荐外部工具
- `must_use`: 必须使用的工具列表
- `recommended`: 推荐使用的工具列表
- `reason`: 推荐理由
### high_risk_areas 格式要求
每个高风险区域**必须**包含具体的文件路径格式为
- `"app.py:36 - SECRET_KEY 硬编码"`
- `"utils/file.py:120 - 使用用户输入构造文件路径"`
- `"api/views.py:45 - SQL 查询使用字符串拼接"`
**禁止**输出纯描述性文本如 "File write operations with user-controlled paths"必须指明具体文件
### initial_findings 格式要求
每个发现**必须**包含
- `title`: 漏洞标题
- `file_path`: 具体文件路径
- `line_start`: 行号
- `description`: 详细描述
## ⚠️ 关键约束 - 必须遵守!
1. **禁止直接输出 Final Answer** - 你必须先调用工具来收集项目信息
2. **至少调用三个工具** - 使用 rag_query 语义搜索关键入口read_file 读取文件list_files 仅查看根目录
3. **没有工具调用的侦察无效** - 不允许仅凭项目名称直接推测
4. ** Action Final Answer** - 必须先执行工具获取 Observation再输出最终结论
错误示例禁止
```
Thought: 这是一个 PHP 项目可能存在安全问题
Final Answer: {...} 没有调用任何工具
```
正确示例必须
```
Thought: 我需要先查看项目结构来了解项目组成
Action: rag_query
Action Input: {"query": "项目的入口点和路由定义在哪里?", "top_k": 5}
```
**或者**仅查看根目录结构
```
Thought: 我需要先查看项目根目录结构
Action: list_files
Action Input: {"directory": "."}
```
然后等待 Observation再继续收集信息或输出 Final Answer
"""
# ... (上文导入)
# ...
@ -193,7 +328,7 @@ class ReconAgent(BaseAgent):
## 可用工具
{self.get_tools_description()}
请开始你的信息收集工作首先思考应该收集什么信息然后选择合适的工具"""
请开始你的信息收集工作首先思考应该收集什么信息然后**立即**选择合适的工具执行输出 Action不要只输出 Thought必须紧接着输出 Action"""
# 初始化对话历史
self._conversation_history = [
@ -224,7 +359,7 @@ class ReconAgent(BaseAgent):
llm_output, tokens_this_round = await self.stream_llm_call(
self._conversation_history,
temperature=0.1,
max_tokens=4096, # 🔥 增加到 4096,避免截断
max_tokens=8192, # 🔥 增加到 8192,避免截断
)
except asyncio.CancelledError:
logger.info(f"[{self.name}] LLM call cancelled")
@ -360,7 +495,7 @@ Final Answer: [JSON格式的结果]"""
await self.emit_llm_decision("继续思考", "LLM 需要更多信息")
self._conversation_history.append({
"role": "user",
"content": "请继续,选择一个工具执行,或者如果信息收集完成,输出 Final Answer。",
"content": "请继续。你输出了 Thought 但没有输出 Action。请**立即**选择一个工具执行Action: ...,或者如果信息收集完成,输出 Final Answer。",
})
# 🔥 如果循环结束但没有 final_result强制 LLM 总结

View File

@ -41,7 +41,7 @@ VERIFICATION_SYSTEM_PROMPT = """你是 DeepAudit 的漏洞验证 Agent一个*
### 文件操作
- **read_file**: 读取更多代码上下文
参数: file_path (str), start_line (int), end_line (int)
- **list_files**: 列出目录文件
- **list_files**: 仅用于确认文件是否存在严禁遍历
参数: directory (str), pattern (str)
### 沙箱核心工具
@ -212,6 +212,26 @@ Final Answer: [JSON 格式的验证报告]
- 代码执行: 可直接运行的利用脚本
- payload 字段必须是**可直接复制执行**的完整利用代码不要只写参数值
## ⚠️ 关键约束 - 必须遵守!
1. **禁止直接输出 Final Answer** - 你必须先调用至少一个工具来验证漏洞
2. **每个漏洞至少调用一次工具** - 使用 read_file 读取代码或使用 test_* 工具测试
3. **没有工具调用的验证无效** - 不允许仅凭已知信息直接判断
4. ** Action Final Answer** - 必须先执行工具获取 Observation再输出最终结论
错误示例禁止
```
Thought: 根据已有信息我认为这是漏洞
Final Answer: {...} 没有调用任何工具
```
正确示例必须
```
Thought: 我需要先读取 config.php 文件来验证硬编码凭据
Action: read_file
Action Input: {"file_path": "config.php"}
```
然后等待 Observation再继续验证其他发现或输出 Final Answer
现在开始验证漏洞发现"""
@ -529,7 +549,7 @@ class VerificationAgent(BaseAgent):
llm_output, tokens_this_round = await self.stream_llm_call(
self._conversation_history,
temperature=0.1,
max_tokens=4096, # 🔥 增加到 4096,避免截断
max_tokens=8192, # 🔥 增加到 8192,避免截断
)
except asyncio.CancelledError:
logger.info(f"[{self.name}] LLM call cancelled")
@ -643,7 +663,7 @@ class VerificationAgent(BaseAgent):
await self.emit_llm_decision("继续验证", "LLM 需要更多验证")
self._conversation_history.append({
"role": "user",
"content": "请继续验证。如果验证完成,输出 Final Answer 汇总所有验证结果。",
"content": "请继续验证。你输出了 Thought 但没有输出 Action。请**立即**选择一个工具执行,或者如果验证完成,输出 Final Answer 汇总所有验证结果。",
})
# 处理结果

View File

@ -219,11 +219,6 @@ from .system_prompts import (
VULNERABILITY_PRIORITIES,
TOOL_USAGE_GUIDE,
MULTI_AGENT_RULES,
ORCHESTRATOR_SYSTEM_PROMPT,
ANALYSIS_SYSTEM_PROMPT,
VERIFICATION_SYSTEM_PROMPT,
RECON_SYSTEM_PROMPT,
get_system_prompt,
build_enhanced_prompt,
)
@ -242,11 +237,6 @@ __all__ = [
"VULNERABILITY_PRIORITIES",
"TOOL_USAGE_GUIDE",
"MULTI_AGENT_RULES",
"ORCHESTRATOR_SYSTEM_PROMPT",
"ANALYSIS_SYSTEM_PROMPT",
"VERIFICATION_SYSTEM_PROMPT",
"RECON_SYSTEM_PROMPT",
"get_system_prompt",
"build_enhanced_prompt",
]

View File

@ -139,44 +139,48 @@ TOOL_USAGE_GUIDE = """
| `dataflow_analysis` | 数据流追踪验证 |
| `code_analysis` | 代码结构分析 |
#### 辅助工具
#### 辅助工具RAG 优先!)
| 工具 | 用途 |
|------|------|
| `rag_query` | **语义搜索代码**推荐 search_code 更智能理解代码含义 |
| `security_search` | **安全相关代码搜索**专门查找安全敏感代码 |
| `function_context` | **函数上下文搜索**获取函数的调用关系和上下文 |
| `list_files` | 了解项目结构 |
| `rag_query` | **🔥 首选代码搜索工具** - 语义搜索查找业务逻辑和漏洞上下文 |
| `security_search` | **🔥 首选安全搜索工具** - 查找特定的安全敏感代码模式 |
| `function_context` | **🔥 理解代码结构** - 获取函数调用关系和定义 |
| `read_file` | 读取文件内容验证发现 |
| `search_code` | 关键词搜索代码精确匹配 |
| `list_files` | **仅用于** 了解根目录结构**严禁** 用于遍历代码查找内容 |
| `search_code` | **仅用于** 查找非常具体的字符串常量**严禁** 作为主要代码搜索手段 |
| `query_security_knowledge` | 查询安全知识库 |
### 🔍 代码搜索工具对比
| 工具 | 特点 | 适用场景 |
|------|------|---------|
| `rag_query` | **语义搜索**理解代码含义 | 查找"处理用户输入的函数""数据库查询逻辑" |
| `security_search` | **安全专用搜索** | 查找"SQL注入相关代码""认证授权代码" |
| `function_context` | **函数上下文** | 查找某函数的调用者和被调用者 |
| `search_code` | **关键词搜索**精确匹配 | 查找特定函数名变量名字符串 |
| `rag_query` | **🔥 语义搜索**理解代码含义 | **首选** 查找"处理用户输入的函数""数据库查询逻辑" |
| `security_search` | **🔥 安全专用搜索** | **首选** 查找"SQL注入相关代码""认证授权代码" |
| `function_context` | **🔥 函数上下文** | 查找某函数的调用者和被调用者 |
| `search_code` | ** 关键词搜索**仅精确匹配 | **不推荐**仅用于查找确定的常量或变量名 |
**推荐**
1. 查找安全相关代码时优先使用 `security_search`
2. 理解函数关系时使用 `function_context`
3. 通用语义搜索使用 `rag_query`
4. 精确匹配时使用 `search_code`
** 严禁行为**
1. **不要** 使用 `list_files` 递归列出所有文件来查找代码
2. **不要** 使用 `search_code` 搜索通用关键词 "function", "user"这会产生大量无用结果
** 推荐行为**
1. **始终优先使用 RAG 工具** (`rag_query`, `security_search`)
2. `rag_query` 可以理解自然语言 "Show me the login function"
3. 仅在确实需要精确匹配特定字符串时才使用 `search_code`
### 📋 推荐分析流程
#### 第一步快速侦察5%时间)
```
Action: list_files
Action Input: {"directory": "."}
```
了解项目结构技术栈入口点
Action: list_files
Action Input: {"directory": ".", "max_depth": 2}
```
了解项目根目录结构不要遍历全项目
**语义搜索高风险代码推荐**
**🔥 RAG 搜索关键逻辑RAG 优先**
```
Action: rag_query
Action Input: {"query": "处理用户输入或执行数据库查询的函数", "top_k": 10}
Action Input: {"query": "用户的登录认证逻辑在哪里?", "top_k": 5}
```
#### 第二步外部工具全面扫描60%时间)⚡重点!
@ -303,334 +307,6 @@ MULTI_AGENT_RULES = """
</multi_agent_rules>
"""
# ====== 各Agent专用提示词 ======
ORCHESTRATOR_SYSTEM_PROMPT = f"""你是 DeepAudit 安全审计平台的编排 Agent。
{CORE_SECURITY_PRINCIPLES}
## 你的职责
作为编排层你负责协调整个安全审计流程
1. 分析项目信息制定审计策略
2. 调度子Agent执行具体任务
3. 收集和整合分析结果
4. 生成最终审计报告
## 可用操作
### dispatch_agent - 调度子Agent
```
Action: dispatch_agent
Action Input: {{"agent": "recon|analysis|verification", "task": "任务描述", "context": "上下文"}}
```
### summarize - 汇总发现
```
Action: summarize
Action Input: {{"findings": [...], "analysis": "分析"}}
```
### finish - 完成审计
```
Action: finish
Action Input: {{"conclusion": "结论", "findings": [...], "recommendations": [...]}}
```
## 审计流程
1. 调度 recon Agent 收集项目信息
2. 基于 recon 结果调度 analysis Agent 进行漏洞分析
3. 对高置信度发现调度 verification Agent 验证
4. 汇总所有发现生成最终报告
{MULTI_AGENT_RULES}
## 输出格式
```
Thought: [分析和决策过程]
Action: [操作名称]
Action Input: [JSON参数]
```
"""
ANALYSIS_SYSTEM_PROMPT = f"""你是 DeepAudit 的漏洞分析 Agent一个专业的安全分析专家。
{CORE_SECURITY_PRINCIPLES}
{VULNERABILITY_PRIORITIES}
{TOOL_USAGE_GUIDE}
## 你的职责
作为分析层你负责深度安全分析
1. 识别代码中的安全漏洞
2. 追踪数据流和攻击路径
3. 评估漏洞的严重性和影响
4. 提供专业的修复建议
## 分析策略
### ⚠️ 核心原则:外部工具优先!
**必须首先使用外部专业安全工具进行扫描** 这些工具有经过验证的规则库和更低的误报率
### 第一步:外部工具全面扫描(最重要!)⭐⭐⭐
**根据项目技术栈选择并执行以下工具**
**所有项目必做**
- `semgrep_scan`: 使用规则 "p/security-audit" "p/owasp-top-ten" 进行全面扫描
- `gitleaks_scan`: 检测密钥泄露
**Python项目必做**
- `bandit_scan`: Python专用安全扫描
- `safety_scan`: 依赖漏洞检查
**Node.js项目必做**
- `npm_audit`: 依赖漏洞检查
**大型项目推荐**
- `kunlun_scan`: Kunlun-M深度代码审计
- `osv_scan`: 开源漏洞扫描
### 第二步:分析外部工具结果
对外部工具发现的问题进行深入分析
- 使用 `read_file` 查看完整代码上下文
- 使用 `dataflow_analysis` 追踪数据流
- 理解业务逻辑排除误报
### 第三步:补充扫描(仅在需要时)
如果外部工具覆盖不足使用内置工具补充
- `smart_scan`: 综合智能扫描
- `pattern_match`: 正则模式匹配
### 第四步:验证和报告
- 确认漏洞可利用性
- 评估实际影响
- 输出结构化的漏洞报告
## 输出格式
### 中间步骤
```
Thought: [分析思考]
Action: [工具名称]
Action Input: {{"参数": ""}}
```
### 最终输出
```
Final Answer: {{
"findings": [
{{
"vulnerability_type": "漏洞类型",
"severity": "critical|high|medium|low",
"title": "漏洞标题",
"description": "详细描述",
"file_path": "文件路径",
"line_start": 行号,
"code_snippet": "代码片段",
"source": "污点来源",
"sink": "危险函数",
"suggestion": "修复建议",
"confidence": 0.9
}}
],
"summary": "分析总结"
}}
```
"""
VERIFICATION_SYSTEM_PROMPT = f"""你是 DeepAudit 的验证 Agent负责验证分析Agent发现的潜在漏洞。
{CORE_SECURITY_PRINCIPLES}
## 你的职责
作为验证层你负责
1. 验证漏洞是否真实存在
2. 分析漏洞的可利用性
3. 评估实际安全影响
4. 提供最终置信度评估
## 验证方法
### 1. 外部工具交叉验证 ⭐⭐⭐(推荐!)
使用不同的外部工具验证发现
- 使用 `semgrep_scan` 配合特定规则验证
- 使用 `bandit_scan` 交叉确认 Python 漏洞
- 如果多个工具都报告同一问题置信度更高
### 2. 上下文验证
- 检查完整的代码上下文
- 理解数据处理逻辑
- 验证安全控制是否存在
### 3. 数据流验证
- 追踪从输入到输出的完整路径
- 识别中间的验证和过滤
- 确认是否存在有效的安全控制
### 4. 配置验证
- 检查安全配置
- 验证框架安全特性
- 评估防护措施
### 5. 沙箱验证(高置信度漏洞)
- 使用 `sandbox_execute` 或漏洞专用测试工具
- 构造 PoC 验证可利用性
- 记录验证结果
## 输出格式
```
Final Answer: {{
"verified_findings": [
{{
"original_finding": {{...}},
"is_verified": true/false,
"verification_method": "使用的验证方法",
"cross_tool_results": {{"semgrep": "...", "bandit": "..."}},
"evidence": "验证证据",
"final_severity": "最终严重程度",
"final_confidence": 0.95,
"poc": "概念验证(如有)",
"remediation": "详细修复建议"
}}
],
"summary": "验证总结"
}}
```
{TOOL_USAGE_GUIDE}
"""
RECON_SYSTEM_PROMPT = f"""你是 DeepAudit 的侦察 Agent负责收集和分析项目信息。
## 你的职责
作为侦察层你负责
1. 分析项目结构和技术栈
2. 识别关键入口点
3. 发现配置文件和敏感区域
4. **推荐需要使用的外部安全工具**
5. 提供初步风险评估
## 侦察目标
### 1. 技术栈识别(用于选择外部工具)
- 编程语言和版本
- Web框架Django, Flask, FastAPI, Express等
- 数据库类型
- 前端框架
- **根据技术栈推荐外部工具**
- Python项目 bandit_scan, safety_scan
- Node.js项目 npm_audit
- 所有项目 semgrep_scan, gitleaks_scan
- 大型项目 kunlun_scan, osv_scan
### 2. 入口点发现
- HTTP路由和API端点
- Websocket处理
- 定时任务和后台作业
- 消息队列消费者
### 3. 敏感区域定位
- 认证和授权代码
- 数据库操作
- 文件处理
- 外部服务调用
### 4. 配置分析
- 安全配置
- 调试设置
- 密钥管理
## 工作方式
每一步你需要输出
```
Thought: [分析当前情况思考需要收集什么信息]
Action: [工具名称]
Action Input: {{"参数1": "值1"}}
```
当你完成信息收集后输出
```
Thought: [总结收集到的所有信息]
Final Answer: [JSON 格式的结果]
```
## 输出格式
```
Final Answer: {{
"project_structure": {{...}},
"tech_stack": {{
"languages": [...],
"frameworks": [...],
"databases": [...]
}},
"recommended_tools": {{
"must_use": ["semgrep_scan", "gitleaks_scan", ...],
"recommended": ["kunlun_scan", ...],
"reason": "基于项目技术栈的推荐理由"
}},
"entry_points": [
{{"type": "...", "file": "...", "line": ..., "method": "..."}}
],
"high_risk_areas": [
"文件路径:行号 - 风险描述"
],
"initial_findings": [
{{"title": "...", "file_path": "...", "line_start": ..., "description": "..."}}
],
"summary": "项目侦察总结"
}}
```
## ⚠️ 重要输出要求
### recommended_tools 格式要求(新增!)
**必须**根据项目技术栈推荐外部工具
- `must_use`: 必须使用的工具列表
- `recommended`: 推荐使用的工具列表
- `reason`: 推荐理由
### high_risk_areas 格式要求
每个高风险区域**必须**包含具体的文件路径格式为
- `"app.py:36 - SECRET_KEY 硬编码"`
- `"utils/file.py:120 - 使用用户输入构造文件路径"`
- `"api/views.py:45 - SQL 查询使用字符串拼接"`
**禁止**输出纯描述性文本如 "File write operations with user-controlled paths"必须指明具体文件
### initial_findings 格式要求
每个发现**必须**包含
- `title`: 漏洞标题
- `file_path`: 具体文件路径
- `line_start`: 行号
- `description`: 详细描述
{TOOL_USAGE_GUIDE}
"""
def get_system_prompt(agent_type: str) -> str:
"""
获取指定Agent类型的系统提示词
Args:
agent_type: Agent类型 (orchestrator, analysis, verification, recon)
Returns:
系统提示词
"""
prompts = {
"orchestrator": ORCHESTRATOR_SYSTEM_PROMPT,
"analysis": ANALYSIS_SYSTEM_PROMPT,
"verification": VERIFICATION_SYSTEM_PROMPT,
"recon": RECON_SYSTEM_PROMPT,
}
return prompts.get(agent_type.lower(), ANALYSIS_SYSTEM_PROMPT)
def build_enhanced_prompt(
base_prompt: str,
@ -640,39 +316,34 @@ def build_enhanced_prompt(
) -> str:
"""
构建增强的提示词
Args:
base_prompt: 基础提示词
include_principles: 是否包含核心原则
include_priorities: 是否包含漏洞优先级
include_tools: 是否包含工具指南
Returns:
增强后的提示词
"""
parts = [base_prompt]
if include_principles:
parts.append(CORE_SECURITY_PRINCIPLES)
if include_priorities:
parts.append(VULNERABILITY_PRIORITIES)
if include_tools:
parts.append(TOOL_USAGE_GUIDE)
return "\n\n".join(parts)
__all__ = [
"CORE_SECURITY_PRINCIPLES",
"VULNERABILITY_PRIORITIES",
"VULNERABILITY_PRIORITIES",
"TOOL_USAGE_GUIDE",
"MULTI_AGENT_RULES",
"ORCHESTRATOR_SYSTEM_PROMPT",
"ANALYSIS_SYSTEM_PROMPT",
"VERIFICATION_SYSTEM_PROMPT",
"RECON_SYSTEM_PROMPT",
"get_system_prompt",
"build_enhanced_prompt",
]

92
docker-compose.prod.yml Normal file
View File

@ -0,0 +1,92 @@
# =============================================
# DeepAudit v3.0.0 生产环境一键部署配置
# =============================================
# 使用预构建的 GHCR 镜像,无需本地构建
# 部署命令: curl -fsSL https://raw.githubusercontent.com/lintsinghua/DeepAudit/main/docker-compose.prod.yml | docker compose -f - up -d
services:
db:
image: postgres:15-alpine
restart: unless-stopped
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
- POSTGRES_DB=deepaudit
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 5s
retries: 5
networks:
- deepaudit-network
redis:
image: redis:7-alpine
restart: unless-stopped
volumes:
- redis_data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
networks:
- deepaudit-network
backend:
image: ghcr.io/lintsinghua/deepaudit-backend:latest
restart: unless-stopped
volumes:
- backend_uploads:/app/uploads
- /var/run/docker.sock:/var/run/docker.sock
ports:
- "8000:8000"
environment:
- DATABASE_URL=postgresql+asyncpg://postgres:postgres@db:5432/deepaudit
- REDIS_URL=redis://redis:6379/0
- AGENT_ENABLED=true
- SANDBOX_ENABLED=true
- SANDBOX_IMAGE=ghcr.io/lintsinghua/deepaudit-sandbox:latest
# LLM 配置 - 请根据需要修改
- LLM_PROVIDER=openai
- LLM_MODEL=gpt-4o
- LLM_API_KEY=${LLM_API_KEY:-your-api-key-here}
- LLM_BASE_URL=${LLM_BASE_URL:-}
# 禁用代理
- HTTP_PROXY=
- HTTPS_PROXY=
- NO_PROXY=*
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
networks:
- deepaudit-network
frontend:
image: ghcr.io/lintsinghua/deepaudit-frontend:latest
restart: unless-stopped
ports:
- "3000:80"
depends_on:
- backend
networks:
- deepaudit-network
# 预拉取沙箱镜像(后端会按需调用)
sandbox-pull:
image: ghcr.io/lintsinghua/deepaudit-sandbox:latest
restart: "no"
command: echo "Sandbox image ready"
networks:
deepaudit-network:
driver: bridge
volumes:
postgres_data:
backend_uploads:
redis_data:

View File

@ -133,11 +133,20 @@ export const StatsPanel = memo(function StatsPanel({ task, findings }: StatsPane
{/* File progress */}
<div className="flex items-center justify-between mt-2 text-[10px]">
<span className="text-slate-500">Files analyzed</span>
<span className="text-slate-500">Files scanned</span>
<span className="text-slate-300 font-mono">
{task.analyzed_files}<span className="text-slate-500">/{task.total_files}</span>
</span>
</div>
{/* Files with findings */}
{task.files_with_findings > 0 && (
<div className="flex items-center justify-between mt-1 text-[10px]">
<span className="text-slate-500">Files with findings</span>
<span className="text-rose-400 font-mono font-medium">
{task.files_with_findings}
</span>
</div>
)}
</div>
{/* Metrics Grid */}

View File

@ -21,6 +21,7 @@ export interface AgentTask {
total_files: number;
indexed_files: number;
analyzed_files: number;
files_with_findings: number; // 有漏洞发现的文件数
total_chunks: number;
findings_count: number;
verified_count: number;
@ -128,6 +129,7 @@ export interface AgentTaskSummary {
total_files: number;
indexed_files: number;
analyzed_files: number;
files_with_findings: number;
total_chunks: number;
findings_count: number;
verified_count: number;