refactor(agent): 重构Agent架构并实现动态Agent树
feat(sandbox): 增强沙箱工具的错误处理和日志记录 test(verification): 添加沙箱验证工具的独立测试脚本 docs: 删除过时的文档和测试文件
This commit is contained in:
parent
e29231cc73
commit
a85cdb687d
|
|
@ -1,93 +0,0 @@
|
|||
# 使用 uv 管理 Python 依赖
|
||||
|
||||
本项目已迁移到使用 [uv](https://github.com/astral-sh/uv) 作为 Python 依赖管理器。
|
||||
|
||||
## 快速开始
|
||||
|
||||
### 安装 uv
|
||||
|
||||
```bash
|
||||
# macOS/Linux
|
||||
curl -LsSf https://astral.sh/uv/install.sh | sh
|
||||
|
||||
# 或使用 Homebrew
|
||||
brew install uv
|
||||
```
|
||||
|
||||
### 安装依赖
|
||||
|
||||
```bash
|
||||
cd backend
|
||||
uv sync
|
||||
```
|
||||
|
||||
这会自动创建虚拟环境并安装所有依赖。
|
||||
|
||||
### 运行项目
|
||||
|
||||
```bash
|
||||
# 激活虚拟环境(uv 会自动管理)
|
||||
uv run uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload
|
||||
|
||||
# 或使用 uv 直接运行
|
||||
uv run python -m uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload
|
||||
```
|
||||
|
||||
### 数据库迁移
|
||||
|
||||
```bash
|
||||
uv run alembic upgrade head
|
||||
```
|
||||
|
||||
### 添加新依赖
|
||||
|
||||
```bash
|
||||
# 添加依赖
|
||||
uv add package-name
|
||||
|
||||
# 添加开发依赖
|
||||
uv add --dev package-name
|
||||
```
|
||||
|
||||
### 更新依赖
|
||||
|
||||
```bash
|
||||
uv sync --upgrade
|
||||
```
|
||||
|
||||
### 其他常用命令
|
||||
|
||||
```bash
|
||||
# 查看已安装的包
|
||||
uv pip list
|
||||
|
||||
# 运行 Python 脚本
|
||||
uv run python script.py
|
||||
|
||||
# 运行 Alembic 命令
|
||||
uv run alembic <command>
|
||||
```
|
||||
|
||||
## 从 pip/venv 迁移
|
||||
|
||||
如果你之前使用 pip 和 venv:
|
||||
|
||||
1. 删除旧的虚拟环境(可选):
|
||||
```bash
|
||||
rm -rf venv
|
||||
```
|
||||
|
||||
2. 使用 uv 同步依赖:
|
||||
```bash
|
||||
uv sync
|
||||
```
|
||||
|
||||
3. 之后使用 `uv run` 运行命令,或激活 uv 创建的虚拟环境。
|
||||
|
||||
## 优势
|
||||
|
||||
- **速度快**:比 pip 快 10-100 倍
|
||||
- **可复现**:自动生成锁文件
|
||||
- **简单**:一个命令管理所有依赖
|
||||
- **兼容**:完全兼容 pip 和 requirements.txt
|
||||
|
||||
|
|
@ -1,82 +0,0 @@
|
|||
# 迁移到 uv 依赖管理器
|
||||
|
||||
## ✅ 已完成的工作
|
||||
|
||||
1. **初始化 uv 项目**
|
||||
- 创建了 `pyproject.toml` 配置文件
|
||||
- 所有依赖已迁移到 `pyproject.toml`
|
||||
|
||||
2. **依赖管理**
|
||||
- 使用 `uv sync` 安装所有依赖
|
||||
- 创建了 `.venv` 虚拟环境(uv 自动管理)
|
||||
- 生成了 `requirements-lock.txt` 锁定文件
|
||||
|
||||
3. **工具和脚本**
|
||||
- 创建了 `start.sh` 启动脚本
|
||||
- 创建了 `README_UV.md` 使用文档
|
||||
|
||||
## 📝 使用方式
|
||||
|
||||
### 启动服务
|
||||
|
||||
```bash
|
||||
cd backend
|
||||
./start.sh
|
||||
```
|
||||
|
||||
或手动启动:
|
||||
|
||||
```bash
|
||||
cd backend
|
||||
uv run uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload
|
||||
```
|
||||
|
||||
### 数据库迁移
|
||||
|
||||
```bash
|
||||
cd backend
|
||||
uv run alembic upgrade head
|
||||
```
|
||||
|
||||
### 添加新依赖
|
||||
|
||||
```bash
|
||||
cd backend
|
||||
uv add package-name
|
||||
```
|
||||
|
||||
## 🔄 从旧环境迁移
|
||||
|
||||
如果你之前使用 `venv` 和 `pip`:
|
||||
|
||||
1. **删除旧虚拟环境**(可选):
|
||||
```bash
|
||||
rm -rf venv
|
||||
```
|
||||
|
||||
2. **使用 uv 同步**:
|
||||
```bash
|
||||
uv sync
|
||||
```
|
||||
|
||||
3. **之后使用 `uv run` 运行所有命令**
|
||||
|
||||
## 📦 依赖文件说明
|
||||
|
||||
- `pyproject.toml` - 项目配置和依赖声明(主要文件)
|
||||
- `requirements.txt` - 保留用于兼容性,但建议使用 `pyproject.toml`
|
||||
- `requirements-lock.txt` - 自动生成的锁定文件(确保可复现)
|
||||
|
||||
## ⚠️ 注意事项
|
||||
|
||||
- uv 创建的虚拟环境在 `.venv/` 目录(不是 `venv/`)
|
||||
- 使用 `uv run` 运行命令会自动使用正确的虚拟环境
|
||||
- 也可以手动激活:`source .venv/bin/activate`
|
||||
|
||||
## 🎯 优势
|
||||
|
||||
- ⚡ **速度快**:比 pip 快 10-100 倍
|
||||
- 🔒 **可复现**:自动生成锁定文件
|
||||
- 🎯 **简单**:一个命令管理所有依赖
|
||||
- 🔄 **兼容**:完全兼容 pip 和 requirements.txt
|
||||
|
||||
|
|
@ -271,6 +271,7 @@ class AgentRunner:
|
|||
}
|
||||
|
||||
# 沙箱工具(仅 Verification Agent 可用)
|
||||
self.sandbox_manager = None
|
||||
try:
|
||||
from app.services.agent.tools.sandbox_tool import SandboxConfig
|
||||
sandbox_config = SandboxConfig(
|
||||
|
|
@ -281,17 +282,27 @@ class AgentRunner:
|
|||
network_mode=settings.SANDBOX_NETWORK_MODE,
|
||||
)
|
||||
self.sandbox_manager = SandboxManager(config=sandbox_config)
|
||||
except Exception as e:
|
||||
logger.warning(f"❌ Sandbox Manager initialization failed: {e}")
|
||||
import traceback
|
||||
logger.warning(f"Traceback: {traceback.format_exc()}")
|
||||
# 尝试创建默认管理器作为后备
|
||||
try:
|
||||
self.sandbox_manager = SandboxManager()
|
||||
logger.info("⚠️ Created fallback SandboxManager (Docker might be unavailable)")
|
||||
except Exception as e2:
|
||||
logger.error(f"❌ Failed to create fallback SandboxManager: {e2}")
|
||||
|
||||
# 始终注册沙箱工具,即使 Docker 不可用(工具内部会检查)
|
||||
if self.sandbox_manager:
|
||||
self.verification_tools["sandbox_exec"] = SandboxTool(self.sandbox_manager)
|
||||
self.verification_tools["sandbox_http"] = SandboxHttpTool(self.sandbox_manager)
|
||||
self.verification_tools["verify_vulnerability"] = VulnerabilityVerifyTool(self.sandbox_manager)
|
||||
logger.info(f"✅ Sandbox tools initialized successfully: sandbox_exec, sandbox_http, verify_vulnerability")
|
||||
logger.info(f"✅ Verification tools: {list(self.verification_tools.keys())}")
|
||||
|
||||
except Exception as e:
|
||||
logger.warning(f"❌ Sandbox initialization failed: {e}")
|
||||
import traceback
|
||||
logger.warning(f"Traceback: {traceback.format_exc()}")
|
||||
logger.info(f"✅ Sandbox tools initialized (Docker available: {self.sandbox_manager.is_available})")
|
||||
else:
|
||||
logger.error("❌ Sandbox tools NOT initialized due to critical manager failure")
|
||||
|
||||
logger.info(f"✅ Verification tools: {list(self.verification_tools.keys())}")
|
||||
|
||||
# 统计总工具数
|
||||
total_tools = len(set(
|
||||
|
|
|
|||
|
|
@ -614,12 +614,15 @@ class SandboxHttpTool(AgentTool):
|
|||
**kwargs
|
||||
) -> ToolResult:
|
||||
"""执行 HTTP 请求"""
|
||||
await self.sandbox_manager.initialize()
|
||||
try:
|
||||
await self.sandbox_manager.initialize()
|
||||
except Exception as e:
|
||||
logger.warning(f"Sandbox init failed during execution: {e}")
|
||||
|
||||
if not self.sandbox_manager.is_available:
|
||||
return ToolResult(
|
||||
success=False,
|
||||
error="沙箱环境不可用",
|
||||
error="沙箱环境不可用 (Docker Unavailable)",
|
||||
)
|
||||
|
||||
result = await self.sandbox_manager.execute_http_request(
|
||||
|
|
@ -716,12 +719,15 @@ class VulnerabilityVerifyTool(AgentTool):
|
|||
**kwargs
|
||||
) -> ToolResult:
|
||||
"""执行漏洞验证"""
|
||||
await self.sandbox_manager.initialize()
|
||||
try:
|
||||
await self.sandbox_manager.initialize()
|
||||
except Exception as e:
|
||||
logger.warning(f"Sandbox init failed during execution: {e}")
|
||||
|
||||
if not self.sandbox_manager.is_available:
|
||||
return ToolResult(
|
||||
success=False,
|
||||
error="沙箱环境不可用",
|
||||
error="沙箱环境不可用 (Docker Unavailable)",
|
||||
)
|
||||
|
||||
result = await self.sandbox_manager.verify_vulnerability(
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import re
|
|||
import logging
|
||||
from typing import Dict, Any, Optional, List
|
||||
from .types import LLMConfig, LLMProvider, LLMMessage, LLMRequest, DEFAULT_MODELS
|
||||
from .factory import LLMFactory
|
||||
from .factory import LLMFactory, NATIVE_ONLY_PROVIDERS
|
||||
from app.core.config import settings
|
||||
|
||||
# json-repair 库用于修复损坏的 JSON
|
||||
|
|
@ -460,8 +460,6 @@ Please analyze the following code:
|
|||
Yields:
|
||||
dict: {"type": "token", "content": str} 或 {"type": "done", ...}
|
||||
"""
|
||||
from .adapters.litellm_adapter import LiteLLMAdapter
|
||||
|
||||
llm_messages = [
|
||||
LLMMessage(role=msg["role"], content=msg["content"])
|
||||
for msg in messages
|
||||
|
|
@ -473,11 +471,46 @@ Please analyze the following code:
|
|||
max_tokens=max_tokens,
|
||||
)
|
||||
|
||||
# 使用 LiteLLM adapter 进行流式调用
|
||||
adapter = LiteLLMAdapter(self.config)
|
||||
|
||||
async for chunk in adapter.stream_complete(request):
|
||||
yield chunk
|
||||
if self.config.provider in NATIVE_ONLY_PROVIDERS:
|
||||
adapter = LLMFactory.create_adapter(self.config)
|
||||
response = await adapter.complete(request)
|
||||
content = response.content or ""
|
||||
usage = None
|
||||
if response.usage:
|
||||
usage = {
|
||||
"prompt_tokens": response.usage.prompt_tokens or 0,
|
||||
"completion_tokens": response.usage.completion_tokens or 0,
|
||||
"total_tokens": response.usage.total_tokens or 0,
|
||||
}
|
||||
if not content:
|
||||
yield {
|
||||
"type": "done",
|
||||
"content": "",
|
||||
"usage": usage,
|
||||
"finish_reason": response.finish_reason or "stop",
|
||||
}
|
||||
else:
|
||||
accumulated = ""
|
||||
chunk_size = 20
|
||||
for i in range(0, len(content), chunk_size):
|
||||
part = content[i:i + chunk_size]
|
||||
accumulated += part
|
||||
yield {
|
||||
"type": "token",
|
||||
"content": part,
|
||||
"accumulated": accumulated,
|
||||
}
|
||||
yield {
|
||||
"type": "done",
|
||||
"content": content,
|
||||
"usage": usage,
|
||||
"finish_reason": response.finish_reason or "stop",
|
||||
}
|
||||
else:
|
||||
from .adapters.litellm_adapter import LiteLLMAdapter
|
||||
adapter = LiteLLMAdapter(self.config)
|
||||
async for chunk in adapter.stream_complete(request):
|
||||
yield chunk
|
||||
|
||||
def _parse_json(self, text: str) -> Dict[str, Any]:
|
||||
"""从LLM响应中解析JSON(增强版)"""
|
||||
|
|
|
|||
|
|
@ -0,0 +1,179 @@
|
|||
|
||||
import asyncio
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
import logging
|
||||
from typing import Dict, Any, List
|
||||
|
||||
# Add backend to path
|
||||
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
|
||||
|
||||
from app.db.session import AsyncSessionLocal
|
||||
from app.models.user_config import UserConfig
|
||||
from app.services.llm.service import LLMService
|
||||
from app.services.agent.agents.verification import VerificationAgent
|
||||
from app.services.agent.tools.sandbox_tool import SandboxTool, SandboxHttpTool, VulnerabilityVerifyTool, SandboxManager, SandboxConfig
|
||||
from app.services.agent.agents.base import AgentType
|
||||
from app.services.agent.config import AgentConfig
|
||||
from app.core.config import settings
|
||||
from sqlalchemy import select
|
||||
|
||||
# Configure logging
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
async def get_user_llm_config():
|
||||
"""Fetch LLM configuration from the first user in the database"""
|
||||
async with AsyncSessionLocal() as session:
|
||||
result = await session.execute(select(UserConfig))
|
||||
user_config = result.scalars().first()
|
||||
|
||||
if not user_config:
|
||||
logger.error("❌ No user config found in database!")
|
||||
return None
|
||||
|
||||
logger.info(f"✅ Loaded config for user_id: {user_config.user_id}")
|
||||
|
||||
import json
|
||||
raw_config = user_config.llm_config
|
||||
llm_data = json.loads(raw_config) if raw_config else {}
|
||||
logger.info(f"📂 Loaded LLM config keys: {list(llm_data.keys())}")
|
||||
|
||||
# Try to find keys regardless of naming convention (camelCase vs snake_case)
|
||||
api_key = llm_data.get("api_key") or llm_data.get("llmApiKey") or llm_data.get("apiKey")
|
||||
base_url = llm_data.get("base_url") or llm_data.get("llmBaseUrl") or llm_data.get("baseUrl")
|
||||
model = llm_data.get("model") or llm_data.get("llmModel")
|
||||
provider = llm_data.get("provider") or llm_data.get("llmProvider")
|
||||
|
||||
return {
|
||||
"api_key": api_key,
|
||||
"base_url": base_url,
|
||||
"model": model,
|
||||
"provider": provider
|
||||
}
|
||||
|
||||
async def run_verification_test():
|
||||
print("\n🚀 Starting Verification Agent Sandbox Test (Standalone Mode)\n")
|
||||
|
||||
llm_config = await get_user_llm_config()
|
||||
if not llm_config:
|
||||
return
|
||||
|
||||
override_provider = os.getenv("TEST_LLM_PROVIDER")
|
||||
override_api_key = os.getenv("TEST_LLM_API_KEY")
|
||||
override_model = os.getenv("TEST_LLM_MODEL")
|
||||
|
||||
if override_provider or override_api_key or override_model:
|
||||
llm_config["provider"] = override_provider or llm_config.get("provider")
|
||||
llm_config["api_key"] = override_api_key or llm_config.get("api_key")
|
||||
llm_config["model"] = override_model or llm_config.get("model")
|
||||
|
||||
# 2. Initialize LLM Service
|
||||
# Transform simple config to the structure LLMService expects
|
||||
service_user_config = {
|
||||
"llmConfig": {
|
||||
"llmProvider": llm_config.get("provider"),
|
||||
"llmApiKey": llm_config.get("api_key"),
|
||||
"llmModel": llm_config.get("model"),
|
||||
"llmBaseUrl": llm_config.get("base_url")
|
||||
}
|
||||
}
|
||||
llm_service = LLMService(user_config=service_user_config)
|
||||
|
||||
# Also update settings just in case
|
||||
if llm_config.get("api_key"):
|
||||
settings.LLM_API_KEY = llm_config["api_key"]
|
||||
|
||||
print(f"🔧 Configured LLM: {llm_config.get('provider')} / {llm_config.get('model')}")
|
||||
|
||||
# 3. Initialize Sandbox Tools
|
||||
print("📦 Initializing Sandbox Tools...")
|
||||
try:
|
||||
sandbox_config = SandboxConfig(
|
||||
image=settings.SANDBOX_IMAGE,
|
||||
memory_limit=settings.SANDBOX_MEMORY_LIMIT,
|
||||
cpu_limit=settings.SANDBOX_CPU_LIMIT,
|
||||
timeout=settings.SANDBOX_TIMEOUT,
|
||||
network_mode=settings.SANDBOX_NETWORK_MODE,
|
||||
)
|
||||
sandbox_manager = SandboxManager(config=sandbox_config)
|
||||
# Pre-check docker
|
||||
await sandbox_manager.initialize()
|
||||
if sandbox_manager.is_available:
|
||||
print("✅ Docker Sandbox is AVAILABLE")
|
||||
else:
|
||||
print("⚠️ Docker Sandbox is UNAVAILABLE (Tools will return error messages)")
|
||||
|
||||
tools = {
|
||||
"sandbox_exec": SandboxTool(sandbox_manager),
|
||||
"sandbox_http": SandboxHttpTool(sandbox_manager),
|
||||
"verify_vulnerability": VulnerabilityVerifyTool(sandbox_manager)
|
||||
}
|
||||
except Exception as e:
|
||||
print(f"❌ Failed to init sandbox: {e}")
|
||||
return
|
||||
|
||||
# 4. Initialize Verification Agent
|
||||
# VerificationAgent.__init__ does not take 'config' argument, it builds it internally.
|
||||
agent = VerificationAgent(
|
||||
llm_service=llm_service,
|
||||
tools=tools
|
||||
)
|
||||
|
||||
# 5. Create Mock Input (Simulating a Command Injection Finding)
|
||||
mock_findings = [
|
||||
{
|
||||
"id": "finding_123",
|
||||
"type": "command_injection",
|
||||
"file": "legacy/vuln.php",
|
||||
"line": 42,
|
||||
"code": "<?php system($_GET['cmd']); ?>",
|
||||
"confidence": "high",
|
||||
"severity": "critical",
|
||||
"description": "User input is directly passed to system() function.",
|
||||
"context": "Legacy admin panel file."
|
||||
}
|
||||
]
|
||||
|
||||
input_data = {
|
||||
"previous_results": {
|
||||
"findings": mock_findings
|
||||
},
|
||||
"task": "Verify this critical command injection vulnerability using sandbox tools.",
|
||||
}
|
||||
|
||||
print("\n🎯 Starting Verification Task...")
|
||||
print(f"Input: {json.dumps(input_data, indent=2, ensure_ascii=False)}")
|
||||
print("-" * 50)
|
||||
|
||||
# 6. Run Agent
|
||||
try:
|
||||
result = await agent.run(input_data)
|
||||
print("\n✅ Verification Completed!")
|
||||
print("-" * 50)
|
||||
if hasattr(result, "model_dump"):
|
||||
print(json.dumps(result.model_dump(), indent=2, ensure_ascii=False))
|
||||
elif hasattr(result, "__dict__"):
|
||||
print(json.dumps(result.__dict__, indent=2, ensure_ascii=False, default=str))
|
||||
else:
|
||||
print(str(result))
|
||||
|
||||
stats = agent.get_stats()
|
||||
print(f"\n📊 Stats: Tool Calls={stats['tool_calls']}, Tokens={stats['tokens_used']}")
|
||||
if stats.get("tool_calls", 0) == 0:
|
||||
print("\n⚠️ LLM 未调用任何工具,直接通过 VerificationAgent.execute_tool 测试 sandbox_exec...")
|
||||
observation = await agent.execute_tool(
|
||||
"sandbox_exec",
|
||||
{"command": "echo sandbox_test", "timeout": 10}
|
||||
)
|
||||
print("\n🔍 Direct sandbox_exec result:")
|
||||
print(observation)
|
||||
|
||||
except Exception as e:
|
||||
print(f"\n❌ Execution Failed: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(run_verification_test())
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
import os
|
||||
import base64
|
||||
|
||||
def test_logo_read():
|
||||
try:
|
||||
# 模拟 ReportGenerator 中的路径逻辑
|
||||
current_dir = os.getcwd() # 假设我们在 backend 目录下运行
|
||||
# 调整逻辑以匹配 ReportGenerator.__file__ 的行为
|
||||
# 假设脚本在 backend/app/services/test_logo.py
|
||||
|
||||
# 直接使用绝对路径进行测试,排除相对路径计算干扰
|
||||
project_root = "/Users/lintsinghua/DeepAudit"
|
||||
logo_path = os.path.join(project_root, 'frontend/public/logo_deepaudit.png')
|
||||
|
||||
print(f"Looking for logo at: {logo_path}")
|
||||
|
||||
if os.path.exists(logo_path):
|
||||
print("File exists.")
|
||||
with open(logo_path, "rb") as image_file:
|
||||
data = image_file.read()
|
||||
b64 = base64.b64encode(data).decode('utf-8')
|
||||
print(f"Read {len(data)} bytes.")
|
||||
print(f"Base64 length: {len(b64)}")
|
||||
print(f"Base64 prefix: {b64[:50]}...")
|
||||
else:
|
||||
print("File does NOT exist.")
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error: {e}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_logo_read()
|
||||
|
|
@ -1,297 +0,0 @@
|
|||
前端页面情况:
|
||||
|
||||
16:18:28
|
||||
🔗 Connected to audit stream
|
||||
16:18:43
|
||||
Orchestrator
|
||||
Thought: 我需要首先了解这个项目的整体结构和功能,以便确定审计的重点。从目录结构来看,这是一个复杂的多模块系统,包含多个引擎(MediaEngine, MindSpider, QueryEngine等)和相关的报告系统。我应该先使用recon Agent来分析项目结构、技术栈和入口点,以便后续有针对性地进行安全审计。
|
||||
16:18:49
|
||||
📤 调度 recon Agent: 分析项目整体结构、技术栈、入口点和主要功能模块...
|
||||
Orchestrator
|
||||
16:18:57
|
||||
Recon
|
||||
Thought: 用户指定了审计范围是1个目标文件:InsightEngine/llms/__init__.py。我需要直接读取和分析这个文件,不要浪费时间遍历其他目录。首先,我应该读取这个文件的内容来了解其结构和功能。
|
||||
16:19:00
|
||||
Completed: read_file
|
||||
Recon
|
||||
0ms
|
||||
16:19:10
|
||||
Recon
|
||||
Thought: 我已经读取了指定的文件 InsightEngine/llms/__init__.py。这是一个简单的Python模块初始化文件,它从.base模块导入了LLMClient类。为了更好地理解这个模块的上下文和依赖关系,我应该搜索项目中是否有其他相关的文件,特别是base.py文件,以及可能使用LLMClient的其他文件。
|
||||
16:19:13
|
||||
Completed: search_code
|
||||
Recon
|
||||
13ms
|
||||
16:19:15
|
||||
Recon
|
||||
Thought: 搜索结果显示LLMClient只在InsightEngine/llms/__init__.py文件中被引用。为了更全面地了解这个模块,我应该查找base.py文件,因为它是LLMClient的定义所在。同时,我也应该搜索项目中是否有其他使用这个LLMClient的文件,以了解它的使用场景。
|
||||
16:19:17
|
||||
Completed: search_code
|
||||
Recon
|
||||
6ms
|
||||
16:19:19
|
||||
Recon
|
||||
Thought: 搜索base.py没有找到结果。让我尝试搜索"from .base"或"import base"来找到base模块的定义位置。同时,我也应该搜索整个项目中是否有其他文件引用了InsightEngine.llms或LLMClient,以了解这个模块的使用范围。
|
||||
16:19:21
|
||||
Completed: search_code
|
||||
Recon
|
||||
6ms
|
||||
16:19:23
|
||||
Recon
|
||||
Thought: 看来base.py文件可能不在审计范围内,或者它可能是一个不存在的文件。让我尝试搜索"InsightEngine"来了解这个模块在整个项目中的使用情况,以及是否有其他相关的LLM或大语言模型相关的文件。
|
||||
16:19:25
|
||||
Completed: search_code
|
||||
Recon
|
||||
8ms
|
||||
16:19:48
|
||||
Recon
|
||||
Thought: 看起来搜索范围仅限于用户指定的单个文件。根据用户的要求,审计范围限定为1个目标文件:InsightEngine/llms/__init__.py。这意味着我只能分析这个文件,而不能访问项目中的其他文件。
|
||||
|
||||
让我总结一下从这个文件中收集到的信息:
|
||||
1. 这是一个名为LLM的模块,为Insight Engine提供统一的OpenAI兼容客户端
|
||||
2. 它从.base模块导入了LLMClient类
|
||||
3. 它通过__all__列表暴露了LLMClient类
|
||||
|
||||
由于base.py文件不在审计范围内,我无法获取LLMClient的具体实现。但根据文件描述,这个模块似乎是一个大语言模型(LLM)客户端,可能与OpenAI API兼容。
|
||||
16:19:58
|
||||
Completed: reflect
|
||||
Recon
|
||||
0ms
|
||||
16:19:59
|
||||
Recon
|
||||
Thought: 我已经完成了对指定文件的分析。由于审计范围被限定为单个文件,我无法获取更多关于项目结构、技术栈、入口点等信息。我现在可以总结收集到的信息并输出最终结果。
|
||||
|
||||
Final Answer:
|
||||
```json
|
||||
{
|
||||
"project_structure": {
|
||||
"directories": [],
|
||||
"config_files": [],
|
||||
"total_files": 1
|
||||
},
|
||||
"tech_stack": {
|
||||
"languages": ["Python"],
|
||||
"frameworks": [],
|
||||
"databases": []
|
||||
},
|
||||
"entry_points": [
|
||||
{"type": "module_init", "file": "InsightEngine/llms/__init__.py", "line": 6}
|
||||
],
|
||||
"high_risk_areas": [],
|
||||
"dependencies": {
|
||||
"internal": ["base.LLMClient"],
|
||||
"external": []
|
||||
},
|
||||
"initial_findings": []
|
||||
}
|
||||
```
|
||||
16:20:05
|
||||
✅ recon Agent 完成
|
||||
Orchestrator
|
||||
16:20:07
|
||||
Orchestrator
|
||||
Thought: Recon Agent的结果显示只分析了1个文件,这与项目目录结构中显示的多个目录和文件不符。这可能是因为Recon Agent没有正确扫描整个项目结构。我需要重新调度Recon Agent,或者直接转向Analysis Agent进行更深入的分析。考虑到项目结构复杂,包含多个引擎模块,我应该尝试让Analysis Agent直接对整个项目进行安全审计,重点关注用户指定的漏洞类型:SQL注入、XSS、命令注入、路径遍历和SSRF。
|
||||
16:20:15
|
||||
📤 调度 analysis Agent: 对整个项目进行安全审计,重点关注SQL注入、XSS、命令注入、路径遍历和SSRF漏洞...
|
||||
Orchestrator
|
||||
16:20:18
|
||||
Analysis
|
||||
Thought: 我需要分析指定的文件 InsightEngine/llms/__init__.py。首先,我应该读取这个文件的内容,了解其结构和功能,然后根据代码内容选择合适的分析工具来检测潜在的安全漏洞。
|
||||
16:20:21
|
||||
Completed: read_file
|
||||
Analysis
|
||||
1ms
|
||||
16:20:23
|
||||
Analysis
|
||||
Thought: 这个文件是一个简单的Python模块初始化文件,它只导入了`LLMClient`类并定义了`__all__`列表。文件本身非常短,没有明显的安全漏洞。但是,为了全面分析,我需要查看被导入的`base.py`文件,因为实际的实现逻辑可能在那里。我应该继续读取`base.py`文件来进行更深入的安全分析。
|
||||
16:20:25
|
||||
Completed: read_file
|
||||
Analysis
|
||||
0ms
|
||||
16:20:43
|
||||
Analysis
|
||||
Thought: 我只能分析用户指定的文件,即 InsightEngine/llms/__init__.py。这个文件本身非常简单,只包含导入语句和模块定义,没有明显的安全漏洞。由于文件内容非常有限,我可以使用 pattern_match 工具来进一步确认是否存在任何潜在的安全模式,尽管从目前来看,这个文件几乎不可能包含安全漏洞。
|
||||
16:20:49
|
||||
Completed: pattern_match
|
||||
Analysis
|
||||
5ms
|
||||
16:21:41
|
||||
Analysis
|
||||
Thought: 我已经完成了对 InsightEngine/llms/__init__.py 文件的分析。这个文件是一个简单的Python模块初始化文件,只包含导入语句和模块定义,没有包含任何可能存在安全漏洞的代码。pattern_match 工具也没有检测到任何已知的危险模式。由于这个文件非常简单且只包含导入语句,它本身不会构成安全风险。我应该总结分析结果。
|
||||
16:21:48
|
||||
Completed: reflect
|
||||
Analysis
|
||||
0ms
|
||||
16:21:50
|
||||
Analysis
|
||||
Thought: 我已经完成了对 InsightEngine/llms/__init__.py 文件的全面安全分析。这个文件非常简单,只包含导入语句和模块定义,没有包含任何可能存在安全漏洞的代码。pattern_match 工具也没有检测到任何已知的危险模式。由于这个文件本身不包含任何业务逻辑或敏感操作,它不会构成安全风险。现在我可以提供最终的分析结果。
|
||||
|
||||
Final Answer: {
|
||||
"findings": [],
|
||||
"summary": "已完成对 InsightEngine/llms/__init__.py 文件的安全分析。该文件是一个简单的Python模块初始化文件,只包含导入语句和模块定义,没有包含任何可能存在安全漏洞的代码。pattern_match 工具也没有检测到任何已知的危险模式。由于这个文件本身不包含任何业务逻辑或敏感操作,它不会构成安全风险。"
|
||||
}
|
||||
16:22:00
|
||||
Analysis
|
||||
```json
|
||||
{
|
||||
"findings": [],
|
||||
"summary": "已完成对 InsightEngine/llms/__init__.py 文件的安全分析。该文件是一个简单的Python模块初始化文件,只包含导入语句和模块定义,没有包含任何可能存在安全漏洞的代码。pattern_match 工具也没有检测到任何已知的危险模式。由于这个文件本身不包含任何业务逻辑或敏感操作,它不会构成安全风险。"
|
||||
}
|
||||
```
|
||||
16:22:04
|
||||
✅ analysis Agent 完成
|
||||
Orchestrator
|
||||
16:22:05
|
||||
Orchestrator
|
||||
Thought: Analysis Agent也没有发现任何漏洞,这很奇怪,因为项目结构复杂且包含多个模块。可能是因为Agent没有正确访问到所有文件。让我尝试直接查看一些关键文件,特别是入口点文件如app.py和report_engine_only.py,这些通常是用户交互的主要入口点,可能包含安全漏洞。
|
||||
16:22:11
|
||||
📤 调度 recon Agent: 重新分析项目,重点关注入口点文件和主要模块...
|
||||
Orchestrator
|
||||
16:22:18
|
||||
Recon
|
||||
Thought: 我需要收集项目信息,但审计范围限定为1个目标文件:InsightEngine/llms/__init__.py。用户还提到之前的分析可能没有正确访问到所有文件,需要关注app.py、report_engine_only.py等入口点文件。我应该先读取指定的目标文件,然后探索项目结构以获取更全面的信息。
|
||||
16:22:22
|
||||
Completed: read_file
|
||||
Recon
|
||||
1ms
|
||||
16:22:23
|
||||
Recon
|
||||
Thought: 我已经读取了指定的目标文件 InsightEngine/llms/__init__.py,这是一个简单的模块初始化文件,它从 .base 导入了 LLMClient 类。现在我需要探索项目结构,了解整个项目的组织方式,特别是用户提到的 app.py、report_engine_only.py 等入口点文件。我将列出根目录的内容来获取项目结构。
|
||||
16:22:28
|
||||
Completed: list_files
|
||||
Recon
|
||||
18ms
|
||||
16:23:05
|
||||
Recon
|
||||
Thought: 系统显示审计范围限定为1个指定文件,但我注意到用户在任务上下文中特别提到了需要关注app.py、report_engine_only.py等入口点文件。我应该尝试搜索这些关键文件,看看它们是否存在于项目中。我将先搜索app.py文件。
|
||||
16:23:08
|
||||
Completed: search_code
|
||||
Recon
|
||||
17ms
|
||||
16:23:11
|
||||
Recon
|
||||
Thought: 没有找到app.py文件。让我尝试搜索report_engine_only.py文件,看看它是否存在。
|
||||
16:23:12
|
||||
Completed: search_code
|
||||
Recon
|
||||
9ms
|
||||
16:23:43
|
||||
Recon
|
||||
Thought: 看来系统中确实只有指定的1个文件。让我尝试搜索其他可能的入口点文件,比如main.py或index.py,看看是否有其他入口点。
|
||||
16:23:46
|
||||
Completed: search_code
|
||||
Recon
|
||||
19ms
|
||||
16:23:47
|
||||
Recon
|
||||
Thought: 系统中似乎只有指定的1个文件。让我尝试搜索Python文件中常见的入口点模式,比如"if __name__ == '__main__'",看看是否有其他入口点代码。
|
||||
16:23:50
|
||||
Completed: search_code
|
||||
Recon
|
||||
9ms
|
||||
16:23:54
|
||||
Recon
|
||||
Thought: 系统中确实只有指定的1个文件。让我尝试搜索其他可能的关键词,比如"Flask"、"Django"等框架相关的关键词,看看是否能推断出技术栈。
|
||||
16:23:57
|
||||
Completed: search_code
|
||||
Recon
|
||||
9ms
|
||||
16:23:58
|
||||
Recon
|
||||
Thought: 让我尝试搜索其他常见的技术栈关键词,比如"import"语句,看看能收集到什么信息。
|
||||
16:24:00
|
||||
Completed: search_code
|
||||
Recon
|
||||
9ms
|
||||
16:24:01
|
||||
Recon
|
||||
Thought: 我找到了一个import语句,它从.base模块导入了LLMClient。让我尝试搜索其他可能的技术栈关键词,比如"from"语句,看看是否有其他导入。
|
||||
16:24:03
|
||||
Completed: search_code
|
||||
Recon
|
||||
8ms
|
||||
16:24:19
|
||||
Recon
|
||||
Thought: 我已经收集了足够的信息。系统中只有指定的1个文件:InsightEngine/llms/__init__.py。这是一个简单的模块初始化文件,它从.base模块导入了LLMClient类。由于系统中只有这一个文件,我无法收集到更多的项目结构、技术栈、入口点等信息。现在我将整理收集到的信息并输出结果。
|
||||
|
||||
Final Answer:
|
||||
```json
|
||||
{
|
||||
"project_structure": {
|
||||
"directories": ["InsightEngine/llms"],
|
||||
"config_files": [],
|
||||
"total_files": 1
|
||||
},
|
||||
"tech_stack": {
|
||||
"languages": ["Python"],
|
||||
"frameworks": [],
|
||||
"databases": []
|
||||
},
|
||||
"entry_points": [
|
||||
{"type": "module_init", "file": "InsightEngine/llms/__init__.py", "line": 6}
|
||||
],
|
||||
"high_risk_areas": [],
|
||||
"dependencies": {},
|
||||
"initial_findings": []
|
||||
}
|
||||
```
|
||||
16:24:52
|
||||
✅ recon Agent 完成
|
||||
Orchestrator
|
||||
16:24:54
|
||||
Orchestrator
|
||||
Thought: Recon Agent仍然只找到了1个文件,这与项目目录结构严重不符。看起来Agent可能无法正确访问项目中的所有文件。考虑到这种情况,我应该尝试直接查看一些关键文件的内容,特别是app.py和report_engine_only.py,这些是项目的主要入口点。我将尝试使用Verification Agent来直接检查这些文件。
|
||||
16:24:58
|
||||
📤 调度 verification Agent: 直接检查项目入口点文件app.py和report_engine_only.py的安全问题...
|
||||
Orchestrator
|
||||
16:24:58
|
||||
✅ verification Agent 完成
|
||||
Orchestrator
|
||||
16:24:58
|
||||
Orchestrator
|
||||
Thought: 所有Agent似乎都无法正确访问项目中的文件,这可能是由于项目访问权限或路径问题导致的。根据用户提供的信息,我们知道项目包含多个目录和文件,但所有Agent都只返回了很少的信息。在这种情况下,我应该基于用户提供的信息和目录结构进行推理分析,并尝试总结可能的安全风险点。
|
||||
16:25:11
|
||||
Orchestrator
|
||||
Thought: 虽然所有Agent都无法直接访问项目文件进行详细分析,但我已经基于项目目录结构进行了推理分析。由于系统限制无法获取更多详细信息,我应该结束审计并总结我的发现和建议。
|
||||
|
||||
|
||||
后端日志:
|
||||
lintsinghua@lintsinghuadeMacBook-Pro backend % uv run uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload
|
||||
INFO: Will watch for changes in these directories: ['/Users/lintsinghua/XCodeReviewer/backend']
|
||||
INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
|
||||
INFO: Started reloader process [94873] using WatchFiles
|
||||
INFO: Started server process [94875]
|
||||
INFO: Waiting for application startup.
|
||||
INFO:app.main:DeepAudit 后端服务启动中...
|
||||
INFO:app.db.init_db:开始初始化数据库...
|
||||
INFO:app.db.init_db:演示账户已存在: demo@example.com
|
||||
INFO:app.db.init_db:演示数据已存在,跳过创建
|
||||
INFO:app.services.init_templates:开始初始化系统模板和规则...
|
||||
INFO:app.services.init_templates:✓ 系统模板和规则初始化完成
|
||||
INFO:app.db.init_db:数据库初始化完成
|
||||
INFO:app.main:✓ 数据库初始化完成
|
||||
INFO:app.main:==================================================
|
||||
INFO:app.main:DeepAudit 后端服务已启动
|
||||
INFO:app.main:API 文档: http://localhost:8000/docs
|
||||
INFO:app.main:==================================================
|
||||
INFO:app.main:演示账户: demo@example.com / demo123
|
||||
INFO:app.main:==================================================
|
||||
INFO: Application startup complete.
|
||||
[Branch] 项目: d, 类型: github, URL: https://github.com/666ghj/BettaFish
|
||||
[Branch] GitHub Token: 未配置, GitLab Token: 未配置
|
||||
[Branch] 警告: GitHub Token 未配置,可能会遇到 API 限制
|
||||
INFO:httpx:HTTP Request: GET https://api.github.com/repos/666ghj/BettaFish/branches?per_page=100 "HTTP/1.1 200 OK"
|
||||
[Branch] 成功获取 7 个分支
|
||||
INFO:httpx:HTTP Request: GET https://api.github.com/repos/666ghj/BettaFish/git/trees/main?recursive=1 "HTTP/1.1 200 OK"
|
||||
INFO:app.api.v1.endpoints.agent_tasks:Created agent task 8717c2de-fedc-4d39-bb19-6b186da9e610 for project d
|
||||
INFO:app.api.v1.endpoints.agent_tasks:✅ Cloned repository https://github.com/666ghj/BettaFish (branch: main) to /tmp/deepaudit/8717c2de-fedc-4d39-bb19-6b186da9e610
|
||||
INFO:app.api.v1.endpoints.agent_tasks:🚀 Task 8717c2de-fedc-4d39-bb19-6b186da9e610 started with Dynamic Agent Tree architecture
|
||||
WARNING:app.services.agent.agents.recon:[Recon] Empty LLM response in iteration 1
|
||||
WARNING:app.services.agent.agents.analysis:[Analysis] Empty LLM response in iteration 4
|
||||
ERROR:app.api.v1.endpoints.agent_tasks:Task 8717c2de-fedc-4d39-bb19-6b186da9e610 failed: property 'progress_percentage' of 'AgentTask' object has no setter
|
||||
Traceback (most recent call last):
|
||||
File "/Users/lintsinghua/XCodeReviewer/backend/app/api/v1/endpoints/agent_tasks.py", line 392, in _execute_agent_task
|
||||
task.progress_percentage = 100.0
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
AttributeError: property 'progress_percentage' of 'AgentTask' object has no setter
|
||||
WARNING: WatchFiles detected changes in 'app/services/llm/adapters/litellm_adapter.py'. Reloading...
|
||||
|
|
@ -1,259 +0,0 @@
|
|||
前端页面输出:
|
||||
|
||||
16:36:05
|
||||
🔗 Connected to audit stream
|
||||
16:36:35
|
||||
Orchestrator
|
||||
Thought: 我需要对这个PHP项目进行安全审计,但审计范围已经限定为单个文件(agent_t/1.php)。由于不需要分析整个项目结构,我可以直接调度analysis Agent对这个文件进行深度安全审计,重点关注用户指定的漏洞类型:SQL注入、XSS、命令注入、路径遍历和SSRF。
|
||||
16:36:44
|
||||
📤 调度 analysis Agent: 对agent_t/1.php文件进行深度安全审计,重点检查sql_injection、xss、command_injection、path_traversal、ssrf等漏洞类型...
|
||||
Orchestrator
|
||||
16:36:51
|
||||
Analysis
|
||||
Thought: 我需要分析agent_t/1.php文件,重点关注SQL注入、XSS、命令注入、路径遍历和SSRF漏洞。首先,我应该读取文件内容,了解代码结构和逻辑,然后使用pattern_match工具进行初步扫描,检测常见的不安全模式。
|
||||
16:36:55
|
||||
Completed: read_file
|
||||
Analysis
|
||||
0ms
|
||||
16:36:56
|
||||
Analysis
|
||||
Thought: 我已经读取了agent_t/1.php文件的内容。这是一个明显包含多种安全漏洞的测试靶场代码。从代码注释可以看出,它故意包含了多种漏洞类型,包括SQL注入、XSS、命令注入、路径遍历、SSRF等。现在我需要使用pattern_match工具进行系统化的漏洞检测,确认这些漏洞并获取详细信息。
|
||||
16:37:45
|
||||
Completed: pattern_match
|
||||
Analysis
|
||||
3ms
|
||||
16:37:46
|
||||
Analysis
|
||||
Thought: pattern_match工具检测到了2个路径遍历漏洞,但我注意到代码中实际上包含更多类型的漏洞。让我使用semgrep_scan工具进行更全面的扫描,以检测所有目标漏洞类型,包括SQL注入、XSS、命令注入等。
|
||||
16:37:50
|
||||
Completed: semgrep_scan
|
||||
Analysis
|
||||
100318ms
|
||||
16:39:31
|
||||
Analysis
|
||||
Thought: semgrep工具不可用,我需要使用其他方法进行漏洞分析。我已经读取了文件内容,可以直接分析代码中的漏洞。从代码中我可以看到多种明显的漏洞,包括SQL注入、XSS、命令注入、路径遍历、SSRF等。让我使用dataflow_analysis工具来追踪一些关键的数据流,特别是用户输入如何流向危险函数。
|
||||
16:39:43
|
||||
Completed: dataflow_analysis
|
||||
Analysis
|
||||
79066ms
|
||||
Input:
|
||||
{
|
||||
"source_code": "$username = $_POST['username'];\n$password = $_POST['password'];\n$sql = \"SELECT * FROM users WHERE username = '$username' AND password = '$password'\";\n$result = mysql_query($sql);",
|
||||
"sink_code": "mysql_query($sql);",
|
||||
"variable_name": "username",
|
||||
"file_path": "agent_t/1.php"
|
||||
}
|
||||
|
||||
Output:
|
||||
null
|
||||
16:41:04
|
||||
Analysis
|
||||
我再尝试分析其他漏洞的数据流,特别是命令注入和XSS部分。
|
||||
16:41:08
|
||||
Completed: dataflow_analysis
|
||||
Analysis
|
||||
63459ms
|
||||
16:42:14
|
||||
Analysis
|
||||
让我尝试分析XSS漏洞的数据流:
|
||||
16:42:18
|
||||
Completed: dataflow_analysis
|
||||
Analysis
|
||||
181539ms
|
||||
Input:
|
||||
{
|
||||
"source_code": "$query = $_GET['q'];\necho \"You searched for: \" . $query;",
|
||||
"sink_code": "echo \"You searched for: \" . $query;",
|
||||
"variable_name": "query",
|
||||
"file_path": "agent_t/1.php"
|
||||
}
|
||||
|
||||
Output:
|
||||
null
|
||||
16:45:22
|
||||
Analysis
|
||||
Thought: dataflow_analysis工具似乎没有返回有用的结果。不过,我已经通过读取文件内容获得了足够的信息来分析漏洞。现在我将总结在agent_t/1.php中发现的所有安全漏洞,并按照要求的格式提供最终报告。
|
||||
|
||||
从代码分析中,我发现了以下漏洞:
|
||||
1. SQL注入(第34行)
|
||||
2. XSS(第77行)
|
||||
3. 命令注入(第50行)
|
||||
4. 路径遍历(第58行)
|
||||
5. SSRF(第66行)
|
||||
6. 硬编码凭证(第18行)
|
||||
7. 不安全的反序列化(第23行)
|
||||
8. 弱加密算法(第39行)
|
||||
9. 敏感信息泄露(第80行)
|
||||
10. 任意文件上传(第86-87行)
|
||||
11. 越权访问(第94行)
|
||||
12. 不安全的随机数生成器(第98行)
|
||||
|
||||
我将按照要求的格式提供最终报告。
|
||||
|
||||
Final Answer: ```json
|
||||
{
|
||||
"findings": [
|
||||
{
|
||||
"vulnerability_type": "sql_injection",
|
||||
"severity": "high",
|
||||
"title": "SQL 注入漏洞",
|
||||
"description": "在登录功能中直接拼接用户输入到SQL查询语句中,没有任何过滤或参数化查询,导致SQL注入漏洞。",
|
||||
"file_path": "agent_t/1.php",
|
||||
"line_start": 34,
|
||||
"code_snippet": "$sql = \"SELECT * FROM users WHERE username = '$username' AND password = '$password'\";",
|
||||
"source": "用户输入 (POST username, password)",
|
||||
"sink": "mysql_query() 函数",
|
||||
"suggestion": "使用参数化查询或预处理语句,避免直接拼接SQL语句。",
|
||||
"confidence": 1.0,
|
||||
"needs_verification": false
|
||||
},
|
||||
{
|
||||
"vulnerability_type": "xss",
|
||||
"severity": "high",
|
||||
"title": "跨站脚本攻击 (XSS)",
|
||||
"description": "在搜索功能中直接输出用户输入,未进行HTML实体编码,导致反射型XSS漏洞。",
|
||||
"file_path": "agent_t/1.php",
|
||||
"line_start": 77,
|
||||
"code_snippet": "echo \"You searched for: \" . $query;",
|
||||
"source": "用户输入 (GET q)",
|
||||
"sink": "echo 输出函数",
|
||||
"suggestion": "对输出进行HTML实体编码,使用htmlspecialchars()函数。",
|
||||
"confidence": 1.0,
|
||||
"needs_verification": false
|
||||
},
|
||||
{
|
||||
"vulnerability_type": "command_injection",
|
||||
"severity": "high",
|
||||
"title": "命令注入漏洞",
|
||||
"description": "在ping功能中直接将用户输入传递给shell_exec函数,导致命令注入漏洞。",
|
||||
"file_path": "agent_t/1.php",
|
||||
"line_start": 50,
|
||||
"code_snippet": "$cmd = shell_exec(\"ping -c 4 \" . $target);",
|
||||
"source": "用户输入 (GET ip)",
|
||||
"sink": "shell_exec() 函数",
|
||||
"suggestion": "验证和过滤用户输入,使用白名单机制,避免直接执行用户提供的命令。",
|
||||
"confidence": 1.0,
|
||||
"needs_verification": false
|
||||
},
|
||||
{
|
||||
"vulnerability_type": "path_traversal",
|
||||
"severity": "high",
|
||||
"title": "路径遍历漏洞",
|
||||
"description": "在view功能中直接使用用户提供的文件名进行文件包含操作,允许读取服务器上的任意文件。",
|
||||
"file_path": "agent_t/1.php",
|
||||
"line_start": 58,
|
||||
"code_snippet": "include($file);",
|
||||
"source": "用户输入 (GET file)",
|
||||
"sink": "include() 函数",
|
||||
"suggestion": "验证和限制文件路径,使用白名单机制,避免路径遍历字符如../",
|
||||
"confidence": 1.0,
|
||||
"needs_verification": false
|
||||
},
|
||||
{
|
||||
"vulnerability_type": "ssrf",
|
||||
"severity": "high",
|
||||
"title": "服务端请求伪造 (SSRF)",
|
||||
"description": "在proxy功能中直接使用用户提供的URL进行文件获取,同时禁用了SSL验证,导致SSRF漏洞。",
|
||||
"file_path": "agent_t/1.php",
|
||||
"line_start": 66,
|
||||
"code_snippet": "$content = file_get_contents($url, false, stream_context_create([\"ssl\" => [\"verify_peer\"=>false, \"verify_peer_name\"=>false]]));",
|
||||
"source": "用户输入 (GET url)",
|
||||
"sink": "file_get_contents() 函数",
|
||||
"suggestion": "验证和限制URL,只允许访问特定域名,启用SSL验证,使用白名单机制。",
|
||||
"confidence": 1.0,
|
||||
"needs_verification": false
|
||||
},
|
||||
{
|
||||
"vulnerability_type": "hardcoded_secrets",
|
||||
"severity": "high",
|
||||
"title": "硬编码凭证",
|
||||
"description": "在代码中硬编码了API密钥,可能导致凭证泄露。",
|
||||
"file_path": "agent_t/1.php",
|
||||
"line_start": 18,
|
||||
"code_snippet": "$secret_api_key = \"12345-SUPER-SECRET-KEY\";",
|
||||
"source": "硬编码值",
|
||||
"sink": "变量存储",
|
||||
"suggestion": "使用环境变量或安全的配置管理系统存储敏感信息。",
|
||||
"confidence": 1.0,
|
||||
"needs_verification": false
|
||||
},
|
||||
{
|
||||
"vulnerability_type": "deserialization",
|
||||
"severity": "high",
|
||||
"title": "不安全的反序列化",
|
||||
"description": "直接从Cookie中反序列化用户数据,可能导致远程代码执行。",
|
||||
"file_path": "agent_t/1.php",
|
||||
"line_start": 23,
|
||||
"code_snippet": "$pref = unserialize($_COOKIE['user_pref']);",
|
||||
"source": "用户输入 (Cookie user_pref)",
|
||||
"sink": "unserialize() 函数",
|
||||
"suggestion": "避免使用不安全的反序列化,使用JSON或其他安全的序列化方法。",
|
||||
"confidence": 1.0,
|
||||
"needs_verification": false
|
||||
},
|
||||
{
|
||||
"vulnerability_type": "weak_crypto",
|
||||
"severity": "medium",
|
||||
"title": "弱加密算法",
|
||||
"description": "使用MD5算法存储或验证密码,MD5已被证明不安全。",
|
||||
"file_path": "agent_t/1.php",
|
||||
"line_start": 39,
|
||||
"code_snippet": "$hash = md5($password);",
|
||||
"source": "用户输入 (POST password)",
|
||||
"sink": "md5() 函数",
|
||||
"suggestion": "使用强哈希算法如bcrypt、Argon2或PBKDF2。",
|
||||
"confidence": 1.0,
|
||||
"needs_verification": false
|
||||
},
|
||||
{
|
||||
"vulnerability_type": "information_disclosure",
|
||||
"severity": "medium",
|
||||
"title": "敏感信息泄露",
|
||||
"description": "在搜索功能中调用phpinfo()函数,泄露大量服务器信息。",
|
||||
"file_path": "agent_t/1.php",
|
||||
"line_start": 80,
|
||||
"code_snippet": "phpinfo();",
|
||||
"source": "直接调用",
|
||||
"sink": "phpinfo() 函数",
|
||||
"suggestion": "移除phpinfo()调用,在生产环境中禁用错误回显。",
|
||||
"confidence": 1.0,
|
||||
"needs_verification": false
|
||||
},
|
||||
{
|
||||
"vulnerability_type": "insecure_random",
|
||||
"severity": "medium",
|
||||
"title": "不安全的随机数生成器",
|
||||
"description": "使用rand()函数生成安全令牌,该函数是可预测的。",
|
||||
"file_path": "agent_t/1.php",
|
||||
"line_start": 98,
|
||||
"code_snippet": "$token = rand(1000, 9999);",
|
||||
"source": "随机数生成",
|
||||
"sink": "令牌生成",
|
||||
"suggestion": "使用random_int()或更安全的随机数生成器。",
|
||||
"confidence": 1.0,
|
||||
"needs_verification": false
|
||||
}
|
||||
],
|
||||
"summary": "agent_t/1.php文件是一个包含多种严重安全漏洞的测试靶场代码。文件中存在SQL注入、XSS、命令注入、路径遍历、SSRF等多种高危漏洞,以及硬编码凭证、不安全的反序列化、弱加密算法等中危漏洞。这些漏洞组合在一起可能导致完全的系统入侵。建议立即修复所有高危漏洞,并重新评估整个应用程序的安全架构。"
|
||||
}
|
||||
```
|
||||
16:47:12
|
||||
✅ analysis Agent 完成
|
||||
Orchestrator
|
||||
16:47:50
|
||||
Orchestrator
|
||||
Thought: analysis Agent已经完成了对agent_t/1.php文件的安全审计,发现了10个安全问题,包括5个高危漏洞和5个中危漏洞。这些漏洞涵盖了用户指定的所有目标漏洞类型(SQL注入、XSS、命令注入、路径遍历、SSRF)以及其他安全问题。现在我需要调度verification Agent来验证这些发现的漏洞,特别是高危漏洞,以确保它们是真实存在的。
|
||||
16:47:53
|
||||
📤 调度 verification Agent: 验证analysis Agent在agent_t/1.php中发现的安全漏洞,特别是高危漏洞:SQL注入、XSS、命令注入、路径遍历、SSRF、硬编码凭证、不安全的反序列化,以及中危漏洞:弱加密算法、...
|
||||
Orchestrator
|
||||
16:47:53
|
||||
✅ verification Agent 完成
|
||||
Orchestrator
|
||||
16:47:53
|
||||
Orchestrator
|
||||
Thought: verification Agent返回的结果显示没有发现任何漏洞,这与analysis Agent的发现形成对比。这可能是因为verification Agent在沙箱环境中无法成功复现漏洞,或者验证过程存在问题。考虑到analysis Agent已经详细分析了代码并发现了多个安全问题,我应该基于analysis Agent的发现来总结审计结果,而不是依赖verification Agent的结果。
|
||||
16:48:11
|
||||
Orchestrator
|
||||
Thought: 我已经完成了对agent_t/1.php文件的安全审计。analysis Agent发现了10个安全问题,包括7个高危漏洞和3个中危漏洞,涵盖了用户指定的所有目标漏洞类型以及其他安全问题。verification Agent没有返回结果,可能是由于沙箱环境的限制。基于analysis Agent的详细分析,我现在可以完成审计并提供结论和建议。
|
||||
16:48:27
|
||||
✅ Audit completed
|
||||
|
|
@ -1,527 +0,0 @@
|
|||
DeepAudit Agent 架构重构升级方案
|
||||
一、现状分析
|
||||
当前 DeepAudit 架构特点
|
||||
DeepAudit 目前采用基于 LangGraph 的固定流程图架构。整个审计流程按照 Recon(信息收集)→ Analysis(漏洞分析)→ Verification(漏洞验证)→ Report(报告生成)的线性顺序执行。每个阶段由一个专门的 Agent 负责,Agent 之间通过 TaskHandoff 机制传递结构化的上下文信息。
|
||||
|
||||
这种架构的优点是流程清晰、易于理解和调试,但存在几个明显的局限性:
|
||||
|
||||
第一,流程过于固定。无论面对什么类型的项目或漏洞,都必须走完整个流程,无法根据实际发现动态调整策略。比如发现了一个 SQL 注入线索,无法立即深入分析,必须等待 Analysis 阶段统一处理。
|
||||
|
||||
第二,Agent 专业化程度不足。Analysis Agent 需要同时处理所有类型的漏洞,从 SQL 注入到 XSS 到 SSRF,这导致系统提示词过于庞大,LLM 难以在每种漏洞类型上都表现出专家级水平。
|
||||
|
||||
第三,缺乏动态协作能力。Agent 之间只能按照预设的顺序传递信息,无法根据需要动态创建新的 Agent 或在 Agent 之间进行实时通信。
|
||||
|
||||
Strix 架构的启示
|
||||
Strix 是一个开源的 AI 安全测试 Agent 项目,它采用了完全不同的架构理念。通过深入分析 Strix 的设计,我们可以获得以下关键启示:
|
||||
|
||||
Strix 的核心是动态 Agent 树结构。根 Agent 可以根据任务需要随时创建子 Agent,每个子 Agent 专注于特定的漏洞类型或任务。子 Agent 完成后向父 Agent 汇报结果,父 Agent 可以根据结果决定是否需要创建更多子 Agent 或进行其他操作。
|
||||
|
||||
Strix 的另一个亮点是模块化的专业知识系统。它为每种漏洞类型都准备了详细的 Jinja2 模板,包含该漏洞的检测方法、利用技术、绕过手段、验证步骤等专业知识。创建 Agent 时可以指定加载哪些知识模块,让 Agent 在特定领域具备专家级能力。
|
||||
|
||||
此外,Strix 还实现了 Agent 间的消息传递机制、完善的状态管理、工具的沙箱执行、LLM 调用优化等高级特性。
|
||||
|
||||
二、升级后的整体架构
|
||||
核心设计理念
|
||||
升级后的 DeepAudit 将采用"动态 Agent 协作 + 专业知识模块 + 智能编排"的三层架构。
|
||||
|
||||
最底层是专业知识模块层,包含各种漏洞类型、框架、技术栈的专业知识库。这些知识以模板形式存储,可以按需加载到 Agent 的系统提示词中。
|
||||
|
||||
中间层是 Agent 执行层,包含可动态创建和销毁的 Agent 实例。每个 Agent 都有完整的生命周期管理,可以执行任务、调用工具、与其他 Agent 通信。
|
||||
|
||||
最上层是智能编排层,负责根据审计目标和实时发现来协调整个审计流程,决定何时创建什么类型的 Agent,如何分配任务,何时结束审计。
|
||||
|
||||
动态 Agent 树
|
||||
与当前固定的四阶段流程不同,升级后的系统将采用动态 Agent 树结构。
|
||||
|
||||
审计开始时,系统创建一个根 Agent(Root Agent)。根 Agent 首先进行初步的信息收集,了解项目的技术栈、目录结构、入口点等基本信息。然后根据收集到的信息,根 Agent 决定需要创建哪些专业子 Agent。
|
||||
|
||||
例如,如果发现项目使用了 SQL 数据库,根 Agent 可能会创建一个专门的 SQL 注入检测 Agent;如果发现有用户输入直接渲染到页面的代码,可能会创建一个 XSS 检测 Agent;如果发现有 HTTP 请求的代码,可能会创建一个 SSRF 检测 Agent。
|
||||
|
||||
每个子 Agent 专注于自己的任务领域。当子 Agent 发现可疑的漏洞线索时,它可以进一步创建验证子 Agent 来确认漏洞是否真实存在。验证通过后,还可以创建报告子 Agent 来生成正式的漏洞报告。
|
||||
|
||||
这种树状结构的好处是:任务可以无限细分,每个 Agent 都能专注于自己擅长的领域;发现和验证可以并行进行,提高效率;根据实际情况动态调整策略,而不是机械地执行固定流程。
|
||||
|
||||
Agent 间通信机制
|
||||
升级后的系统将实现完善的 Agent 间通信机制。
|
||||
|
||||
每个 Agent 都有一个消息队列,其他 Agent 可以向这个队列发送消息。消息类型包括:查询消息(请求信息)、指令消息(要求执行某个操作)、信息消息(分享发现或状态)。
|
||||
|
||||
当 Agent 处于等待状态时,它会检查自己的消息队列。如果有新消息,Agent 会处理消息并可能恢复执行。这种机制使得 Agent 之间可以进行实时协作,而不仅仅是单向的结果传递。
|
||||
|
||||
例如,SQL 注入检测 Agent 在分析过程中发现某个函数可能存在问题,但需要了解这个函数的调用上下文。它可以向根 Agent 发送查询消息,请求提供相关信息。根 Agent 收到消息后,可以调用代码搜索工具获取信息,然后回复给 SQL 注入检测 Agent。
|
||||
|
||||
Agent 状态管理
|
||||
每个 Agent 都有完整的状态管理,状态信息包括:
|
||||
|
||||
基本信息:Agent 的唯一标识、名称、父 Agent 标识、创建时间等。
|
||||
|
||||
任务信息:当前任务描述、任务上下文、从父 Agent 继承的信息等。
|
||||
|
||||
执行状态:当前迭代次数、最大迭代限制、运行状态(运行中、等待中、已完成、失败、已停止)等。
|
||||
|
||||
对话历史:与 LLM 的完整对话记录,包括系统提示词、用户消息、助手回复等。
|
||||
|
||||
执行记录:已执行的动作列表、观察结果列表、错误记录等。
|
||||
|
||||
发现列表:该 Agent 发现的所有漏洞和可疑点。
|
||||
|
||||
这种完整的状态管理使得 Agent 可以被暂停和恢复,可以被序列化和持久化,也便于调试和审计。
|
||||
|
||||
三、专业知识模块系统
|
||||
模块化设计
|
||||
专业知识模块是升级后架构的核心创新之一。我们将为不同的漏洞类型、框架、技术栈创建专门的知识模块。
|
||||
|
||||
漏洞类型模块包括:SQL 注入、XSS、SSRF、IDOR、认证绕过、远程代码执行、路径遍历、XXE、CSRF、竞态条件、反序列化、业务逻辑漏洞等。每个模块都包含该漏洞类型的完整知识体系。
|
||||
|
||||
框架知识模块包括:FastAPI、Django、Flask、Express、Next.js、Spring、Laravel 等主流框架。每个模块包含该框架的安全特性、常见漏洞模式、最佳实践等。
|
||||
|
||||
技术栈模块包括:Supabase、Firebase、GraphQL、gRPC、WebSocket 等。每个模块包含该技术的安全考量和常见问题。
|
||||
|
||||
模块内容结构
|
||||
以 SQL 注入模块为例,它应该包含以下内容:
|
||||
|
||||
漏洞概述:SQL 注入的定义、危害、影响范围。
|
||||
|
||||
检测方法:错误型注入检测、布尔型注入检测、时间型注入检测、带外注入检测的具体技术和判断标准。
|
||||
|
||||
数据库特定知识:MySQL、PostgreSQL、MSSQL、Oracle 等不同数据库的特有语法、函数、利用技术。
|
||||
|
||||
绕过技术:WAF 绕过、过滤绕过、编码绕过等高级技术。
|
||||
|
||||
ORM 和查询构建器:各种 ORM 框架中容易出现 SQL 注入的 API 和模式。
|
||||
|
||||
验证步骤:如何确认漏洞真实存在,如何构造 PoC,如何评估影响。
|
||||
|
||||
误报识别:哪些情况容易被误判为 SQL 注入,如何排除误报。
|
||||
|
||||
修复建议:参数化查询、ORM 正确用法、输入验证等修复方案。
|
||||
|
||||
模块加载机制
|
||||
创建 Agent 时,可以指定该 Agent 需要加载哪些知识模块。系统会将这些模块的内容动态注入到 Agent 的系统提示词中。
|
||||
|
||||
为了控制提示词长度和保持 Agent 的专注度,每个 Agent 最多加载 5 个知识模块。这个限制迫使我们为每个 Agent 选择最相关的知识,而不是试图让一个 Agent 掌握所有知识。
|
||||
|
||||
模块之间可以有依赖关系。例如,FastAPI 框架模块可能依赖 Python 安全基础模块;GraphQL 模块可能依赖 API 安全基础模块。加载模块时会自动处理这些依赖。
|
||||
|
||||
四、工具系统升级
|
||||
统一的工具注册机制
|
||||
升级后的工具系统将采用装饰器模式进行统一注册。每个工具都需要提供:工具名称、功能描述、参数定义、返回值说明。
|
||||
|
||||
工具按类别组织,包括:文件操作类(读取文件、搜索文件、列出目录)、代码分析类(模式匹配、数据流分析、AST 分析)、外部扫描类(Semgrep、Bandit、Gitleaks 等)、验证执行类(沙箱命令执行、HTTP 请求)、协作类(创建子 Agent、发送消息、等待消息)、推理类(思考工具)、报告类(创建漏洞报告)。
|
||||
|
||||
Think 工具
|
||||
Think 工具是从 Strix 借鉴的关键创新。这是一个让 Agent 进行深度推理的工具,Agent 可以用它来:
|
||||
|
||||
分析复杂情况:当面对复杂的代码逻辑或不确定的漏洞线索时,Agent 可以调用 Think 工具进行深入思考。
|
||||
|
||||
规划下一步行动:在执行具体操作之前,先用 Think 工具规划策略。
|
||||
|
||||
评估发现的严重性:发现可疑点后,用 Think 工具评估其真实性和影响。
|
||||
|
||||
决定是否需要创建子 Agent:当任务变得复杂时,用 Think 工具分析是否需要分解任务。
|
||||
|
||||
Think 工具的输出会被记录到 Agent 的对话历史中,帮助 LLM 保持思路的连贯性。
|
||||
|
||||
漏洞报告工具
|
||||
漏洞报告工具是正式记录漏洞的唯一方式。只有通过这个工具创建的漏洞才会被计入最终报告。这个设计确保了漏洞报告的规范性和完整性。
|
||||
|
||||
报告工具要求提供完整的漏洞信息:漏洞类型、严重程度、标题、详细描述、文件位置、代码片段、PoC、影响分析、修复建议等。
|
||||
|
||||
通常只有专门的报告 Agent 才会调用这个工具,确保漏洞在被正式报告之前已经经过了充分的验证。
|
||||
|
||||
沙箱执行
|
||||
涉及代码执行或网络请求的工具都在沙箱环境中运行。沙箱提供资源隔离(CPU、内存、网络限制)、文件系统隔离、超时控制等安全保障。
|
||||
|
||||
沙箱执行通过 Tool Server 机制实现。Agent 发送工具调用请求到 Tool Server,Tool Server 在沙箱中执行工具并返回结果。这种设计使得即使工具执行出现问题,也不会影响主系统的稳定性。
|
||||
|
||||
五、LLM 调用优化
|
||||
Prompt Caching
|
||||
对于支持 Prompt Caching 的 LLM(如 Anthropic Claude),系统会自动为系统提示词和早期对话添加缓存标记。这样在多轮对话中,这些内容只需要处理一次,后续调用可以直接使用缓存,显著降低 Token 消耗和响应延迟。
|
||||
|
||||
缓存策略会根据对话长度动态调整。对于短对话,只缓存系统提示词;对于长对话,会在关键位置添加多个缓存点。
|
||||
|
||||
Memory Compression
|
||||
当对话历史变得很长时,系统会自动进行压缩。压缩策略包括:
|
||||
|
||||
移除冗余信息:重复的工具调用结果、过长的代码输出等会被截断或摘要。
|
||||
|
||||
合并相似消息:连续的同类型消息可能被合并。
|
||||
|
||||
保留关键信息:重要的发现、决策点、错误信息等会被优先保留。
|
||||
|
||||
压缩后的对话历史仍然保持语义完整性,LLM 可以理解之前发生了什么,但 Token 消耗大大降低。
|
||||
|
||||
智能重试
|
||||
LLM 调用可能因为各种原因失败:网络问题、速率限制、服务不可用等。系统实现了智能重试机制:
|
||||
|
||||
对于可重试的错误(如速率限制),会等待适当时间后重试。
|
||||
|
||||
对于不可重试的错误(如认证失败),会立即报错并提供清晰的错误信息。
|
||||
|
||||
重试时会使用指数退避策略,避免对 LLM 服务造成过大压力。
|
||||
|
||||
六、审计流程重构
|
||||
启动阶段
|
||||
用户发起审计请求后,系统首先创建根 Agent。根 Agent 加载通用的安全审计知识模块和项目相关的框架知识模块。
|
||||
|
||||
根 Agent 的第一个任务是信息收集:扫描项目目录结构、识别技术栈、找出入口点、分析依赖关系。这个阶段类似于当前的 Recon 阶段,但更加灵活。
|
||||
|
||||
任务分解阶段
|
||||
根据信息收集的结果,根 Agent 决定如何分解审计任务。它会考虑:
|
||||
|
||||
项目使用了哪些技术?需要创建哪些专业 Agent?
|
||||
|
||||
有哪些高风险区域?应该优先分析哪些部分?
|
||||
|
||||
项目规模如何?需要多少并行 Agent?
|
||||
|
||||
根 Agent 会创建一批初始的子 Agent,每个子 Agent 负责特定的漏洞类型或代码区域。
|
||||
|
||||
并行分析阶段
|
||||
多个子 Agent 并行工作,各自在自己的专业领域进行深入分析。
|
||||
|
||||
每个子 Agent 都有自己的工作循环:思考当前状态、选择工具执行、观察结果、决定下一步。这个循环会持续进行,直到 Agent 认为任务完成或达到迭代限制。
|
||||
|
||||
子 Agent 在分析过程中可能会发现需要进一步调查的线索。这时它可以创建更专业的子 Agent 来处理,形成多层的 Agent 树。
|
||||
|
||||
验证阶段
|
||||
当分析 Agent 发现可疑的漏洞时,它会创建验证 Agent 来确认漏洞是否真实存在。
|
||||
|
||||
验证 Agent 会尝试构造 PoC、进行数据流追踪、在沙箱中测试等。验证通过后,验证 Agent 会创建报告 Agent 来生成正式的漏洞报告。
|
||||
|
||||
如果验证失败,验证 Agent 会将结果反馈给父 Agent,父 Agent 可以决定是否需要进一步调查或将其标记为误报。
|
||||
|
||||
汇总阶段
|
||||
当所有子 Agent 都完成工作后,根 Agent 会汇总所有发现,生成最终的审计报告。
|
||||
|
||||
报告包括:发现的所有漏洞(按严重程度排序)、安全评分、技术栈分析、高风险区域标注、修复建议优先级等。
|
||||
|
||||
七、可观测性和调试
|
||||
完整的事件追踪
|
||||
系统会记录所有重要事件:Agent 创建和销毁、工具调用和结果、LLM 请求和响应、Agent 间消息、状态变更等。
|
||||
|
||||
这些事件可以实时推送到前端,让用户看到审计的进展。也可以持久化到数据库,用于后续分析和审计。
|
||||
|
||||
Agent 树可视化
|
||||
前端可以展示当前的 Agent 树结构,显示每个 Agent 的状态、任务、发现数量等信息。用户可以点击任何 Agent 查看其详细信息和对话历史。
|
||||
|
||||
调试模式
|
||||
在调试模式下,系统会记录更详细的信息,包括完整的 LLM 提示词和响应、工具执行的详细日志、状态变更的完整历史等。这些信息对于排查问题和优化系统非常有价值。
|
||||
|
||||
八、与现有架构的兼容
|
||||
渐进式迁移
|
||||
升级不需要一次性完成,可以渐进式进行。
|
||||
|
||||
第一步,保持现有的 LangGraph 流程不变,但将 Agent 的状态管理升级为新的模型。
|
||||
|
||||
第二步,引入专业知识模块系统,让现有的 Analysis Agent 可以加载不同的知识模块。
|
||||
|
||||
第三步,在 Analysis 阶段内部引入子 Agent 机制,允许创建专业的漏洞检测子 Agent。
|
||||
|
||||
第四步,逐步放开流程限制,让 Agent 可以更灵活地决定下一步操作。
|
||||
|
||||
第五步,完全迁移到动态 Agent 树架构。
|
||||
|
||||
保留 LangGraph 的优势
|
||||
LangGraph 提供了很好的状态管理和检查点机制,这些在新架构中仍然有价值。我们可以将 LangGraph 用于根 Agent 的高层编排,而在子 Agent 层面使用更灵活的动态创建机制。
|
||||
|
||||
九、预期收益
|
||||
更深度的漏洞发现
|
||||
专业知识模块让每个 Agent 都具备安全专家级别的知识。专注于单一漏洞类型的 Agent 比通用 Agent 更容易发现深层次的问题。
|
||||
|
||||
更高的效率
|
||||
并行的 Agent 执行比串行流程更快。动态任务分解避免了在无关区域浪费时间。
|
||||
|
||||
更低的成本
|
||||
Prompt Caching 和 Memory Compression 显著降低 Token 消耗。专业化的 Agent 使用更短的提示词就能达到更好的效果。
|
||||
|
||||
更好的可扩展性
|
||||
添加新的漏洞类型只需要创建新的知识模块。支持新的框架只需要添加框架知识模块。整个系统的扩展不需要修改核心架构。
|
||||
|
||||
更强的可解释性
|
||||
完整的事件追踪和 Agent 树可视化让用户清楚地了解系统在做什么。Think 工具的输出展示了 Agent 的推理过程。
|
||||
|
||||
这个升级方案借鉴了 Strix 的核心设计理念,同时保留了 DeepAudit 的既有优势,通过渐进式迁移降低风险,最终实现一个更强大、更灵活、更专业的安全审计 Agent 系统。
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 十、实施进度记录
|
||||
|
||||
### 已完成的工作 (2024-12)
|
||||
|
||||
#### 1. 核心模块系统 ✅
|
||||
- `core/state.py`: 增强的Agent状态管理,支持完整生命周期
|
||||
- `core/registry.py`: Agent注册表和动态Agent树管理
|
||||
- `core/message.py`: Agent间通信机制(消息总线)
|
||||
|
||||
#### 2. 专业知识模块系统 ✅ (基于RAG)
|
||||
采用模块化文件组织,统一使用RAG进行知识检索:
|
||||
|
||||
```
|
||||
knowledge/
|
||||
├── base.py # 基础定义(KnowledgeDocument, KnowledgeCategory)
|
||||
├── loader.py # 知识加载器
|
||||
├── rag_knowledge.py # RAG检索系统
|
||||
├── tools.py # 知识查询工具
|
||||
├── vulnerabilities/ # 漏洞类型知识
|
||||
│ ├── injection.py # SQL注入、NoSQL注入、命令注入、代码注入
|
||||
│ ├── xss.py # 反射型XSS、存储型XSS、DOM型XSS
|
||||
│ ├── auth.py # 认证绕过、IDOR、访问控制失效
|
||||
│ ├── crypto.py # 弱加密、硬编码凭证
|
||||
│ ├── ssrf.py # SSRF
|
||||
│ ├── deserialization.py # 不安全的反序列化
|
||||
│ ├── path_traversal.py # 路径遍历
|
||||
│ ├── xxe.py # XXE
|
||||
│ └── race_condition.py # 竞态条件
|
||||
└── frameworks/ # 框架安全知识
|
||||
├── fastapi.py # FastAPI安全
|
||||
├── django.py # Django安全
|
||||
├── flask.py # Flask安全
|
||||
├── express.py # Express.js安全
|
||||
├── react.py # React安全
|
||||
└── supabase.py # Supabase安全
|
||||
```
|
||||
|
||||
#### 3. Agent基类增强 ✅
|
||||
- 支持动态Agent树(parent_id, 子Agent创建)
|
||||
- Agent间消息通信
|
||||
- TaskHandoff协作机制
|
||||
- 知识模块加载
|
||||
- Memory Compression集成
|
||||
|
||||
#### 4. 工具系统 ✅
|
||||
- `thinking_tool.py`: Think和Reflect工具
|
||||
- `reporting_tool.py`: 漏洞报告工具
|
||||
- `agent_tools.py`: Agent协作工具
|
||||
- CreateSubAgentTool: 动态创建子Agent
|
||||
- SendMessageTool: Agent间消息发送
|
||||
- ViewAgentGraphTool: 查看Agent树
|
||||
- WaitForMessageTool: 等待消息
|
||||
- AgentFinishTool: 子Agent完成报告
|
||||
|
||||
#### 5. LLM调用优化 ✅
|
||||
- `memory_compressor.py`: 对话历史压缩
|
||||
- 自动检测是否需要压缩
|
||||
- 保留关键信息(发现、工具使用、决策、错误)
|
||||
- 智能摘要生成
|
||||
- Agent基类集成自动压缩
|
||||
|
||||
#### 6. Orchestrator Agent ✅
|
||||
- LLM驱动的编排决策
|
||||
- 动态调度子Agent
|
||||
- ReAct模式执行
|
||||
|
||||
### 已完成的工作 (2024-12 续)
|
||||
|
||||
#### 7. Prompt Caching ✅
|
||||
- `llm/prompt_cache.py`: Prompt 缓存管理器
|
||||
- 支持 Anthropic Claude 的 Prompt Caching
|
||||
- 动态缓存策略(SYSTEM_ONLY, SYSTEM_AND_EARLY, MULTI_POINT)
|
||||
- 缓存统计和效果追踪
|
||||
- Token 估算工具
|
||||
- LiteLLM 适配器集成缓存支持
|
||||
|
||||
#### 8. 动态Agent树执行器 ✅
|
||||
- `core/executor.py`: 完整的执行器实现
|
||||
- `DynamicAgentExecutor`: 动态Agent树执行器
|
||||
- 并行Agent执行(带信号量控制)
|
||||
- 任务依赖管理
|
||||
- 执行结果汇总
|
||||
- 超时和取消处理
|
||||
- `SubAgentExecutor`: 子Agent执行器
|
||||
- 从父Agent创建和执行子Agent
|
||||
- 并行子Agent执行
|
||||
- 结果收集和汇总
|
||||
- `ExecutionTask`: 执行任务数据结构
|
||||
- `ExecutionResult`: 执行结果数据结构
|
||||
|
||||
#### 9. Agent状态持久化 ✅
|
||||
- `core/persistence.py`: 持久化模块
|
||||
- `AgentStatePersistence`: 状态持久化管理器
|
||||
- 文件系统持久化
|
||||
- 数据库持久化(可选)
|
||||
- 检查点列表和清理
|
||||
- `CheckpointManager`: 检查点管理器
|
||||
- 自动检查点(按迭代间隔)
|
||||
- 检查点恢复
|
||||
- 状态回滚
|
||||
|
||||
#### 10. 增强的Agent协作工具 ✅
|
||||
- `CreateSubAgentTool`: 增强版
|
||||
- 支持立即执行模式
|
||||
- 集成SubAgentExecutor
|
||||
- 上下文传递
|
||||
- `RunSubAgentsTool`: 批量执行子Agent
|
||||
- 并行/顺序执行
|
||||
- 结果汇总
|
||||
- `CollectSubAgentResultsTool`: 收集子Agent结果
|
||||
|
||||
#### 11. 数据库模型扩展 ✅
|
||||
- `AgentCheckpoint`: Agent检查点模型
|
||||
- 状态数据存储
|
||||
- 执行统计
|
||||
- 检查点类型(auto/manual/error/final)
|
||||
- `AgentTreeNode`: Agent树节点模型
|
||||
- 树结构记录
|
||||
- 执行状态追踪
|
||||
- 结果汇总
|
||||
- Alembic迁移脚本: `007_add_agent_checkpoint_tables.py`
|
||||
|
||||
#### 12. API 端点 ✅
|
||||
- `GET /agent-tasks/{task_id}/agent-tree`: Agent树查询API
|
||||
- 返回完整的Agent树结构
|
||||
- 支持运行时内存查询和数据库查询
|
||||
- 包含执行状态和发现统计
|
||||
- `GET /agent-tasks/{task_id}/checkpoints`: 检查点列表API
|
||||
- 支持按Agent ID过滤
|
||||
- 分页支持
|
||||
- `GET /agent-tasks/{task_id}/checkpoints/{checkpoint_id}`: 检查点详情API
|
||||
- 返回完整的Agent状态数据
|
||||
|
||||
### 已完成的工作 (2024-12 续2)
|
||||
|
||||
#### 13. 前端 Agent 审计页面 ✅ (Strix-inspired Terminal UI)
|
||||
- `frontend/src/shared/api/agentTasks.ts`: 扩展 API
|
||||
- `AgentTreeNode`, `AgentTreeResponse` 类型定义
|
||||
- `AgentCheckpoint`, `CheckpointDetail` 类型定义
|
||||
- `getAgentTree()`: 获取 Agent 树结构
|
||||
- `getAgentCheckpoints()`: 获取检查点列表
|
||||
- `getCheckpointDetail()`: 获取检查点详情
|
||||
|
||||
- `frontend/src/pages/AgentAudit.tsx`: 统一的 Agent 审计页面 (参考 Strix TUI 设计)
|
||||
- **布局**: 左侧活动日志 (75%) + 右侧 Agent 树和统计 (25%)
|
||||
- **启动画面**: ASCII Art + 动画加载效果
|
||||
- **活动日志**:
|
||||
- 实时流式显示 Agent 思考过程
|
||||
- 工具调用和结果展示
|
||||
- 漏洞发现高亮
|
||||
- 自动滚动控制
|
||||
- 可折叠的日志条目
|
||||
- **Agent 树可视化**:
|
||||
- 树状结构展示
|
||||
- 节点状态图标(运行中/已完成/失败/等待)
|
||||
- 发现数量徽章
|
||||
- 节点选择交互
|
||||
- **实时统计面板**:
|
||||
- 进度百分比
|
||||
- 文件分析进度
|
||||
- Token 使用量
|
||||
- 发现数量
|
||||
- 严重程度分布
|
||||
- **创建任务对话框**: 选择项目后直接跳转到实时流页面
|
||||
- **任务控制**: 停止/取消任务
|
||||
|
||||
- `frontend/src/app/routes.tsx`: 路由配置
|
||||
- `/agent-audit`: 启动画面 + 创建任务
|
||||
- `/agent-audit/:taskId`: 任务实时流页面
|
||||
|
||||
- `frontend/src/components/layout/Sidebar.tsx`: 侧边栏导航
|
||||
- 新增 Agent 审计入口图标
|
||||
|
||||
### 已完成的工作 (2024-12 续3)
|
||||
|
||||
#### 14. 执行架构切换 ✅
|
||||
- **移除旧的 LangGraph 固定流程架构**
|
||||
- **启用新的动态 Agent 树架构**
|
||||
- `backend/app/api/v1/endpoints/agent_tasks.py`:
|
||||
- `_execute_agent_task()` 重写为使用 `OrchestratorAgent`
|
||||
- OrchestratorAgent 作为大脑,动态调度子 Agent
|
||||
- 子 Agent: ReconAgent, AnalysisAgent, VerificationAgent
|
||||
- 新增辅助函数: `_get_user_config()`, `_initialize_tools()`, `_collect_project_info()`, `_save_findings()`, `_calculate_security_score()`
|
||||
|
||||
### 待完成的工作
|
||||
|
||||
#### 1. 前端增强
|
||||
- 知识模块选择 UI(创建任务时)
|
||||
- 检查点恢复功能
|
||||
- 导出报告功能
|
||||
|
||||
#### 2. 测试和优化
|
||||
- 单元测试
|
||||
- 集成测试
|
||||
- 性能优化
|
||||
- 并发执行压力测试
|
||||
|
||||
#### 3. 文档
|
||||
- API文档更新
|
||||
- 架构图更新
|
||||
- 使用指南
|
||||
|
||||
---
|
||||
|
||||
## 十一、架构升级总结
|
||||
|
||||
### 已实现的核心功能
|
||||
|
||||
1. **Prompt Caching** - 为 Claude 等 LLM 提供缓存支持,减少 Token 消耗
|
||||
2. **动态 Agent 树执行** - OrchestratorAgent 作为大脑,动态调度子 Agent
|
||||
3. **Agent 状态持久化** - 文件系统和数据库双重持久化
|
||||
4. **检查点机制** - 自动检查点、状态恢复、执行历史追踪
|
||||
5. **增强的协作工具** - 子 Agent 创建、批量执行、结果收集
|
||||
6. **完整的 API 支持** - Agent 树查询、检查点管理
|
||||
7. **旧架构已移除** - 不再使用 LangGraph 固定流程,完全切换到动态 Agent 树
|
||||
|
||||
### 文件清单
|
||||
|
||||
```
|
||||
backend/app/services/
|
||||
├── llm/
|
||||
│ ├── __init__.py # 模块导出
|
||||
│ ├── prompt_cache.py # 🆕 Prompt Caching
|
||||
│ ├── memory_compressor.py # Memory Compression
|
||||
│ └── adapters/
|
||||
│ └── litellm_adapter.py # 集成 Prompt Caching
|
||||
│
|
||||
├── agent/
|
||||
│ ├── core/
|
||||
│ │ ├── __init__.py # 模块导出
|
||||
│ │ ├── state.py # Agent 状态管理
|
||||
│ │ ├── registry.py # Agent 注册表
|
||||
│ │ ├── message.py # Agent 间通信
|
||||
│ │ ├── executor.py # 🆕 动态 Agent 树执行器
|
||||
│ │ └── persistence.py # 🆕 状态持久化
|
||||
│ │
|
||||
│ ├── tools/
|
||||
│ │ ├── __init__.py # 模块导出
|
||||
│ │ ├── agent_tools.py # 🔄 增强的协作工具
|
||||
│ │ ├── thinking_tool.py # Think/Reflect 工具
|
||||
│ │ └── reporting_tool.py # 漏洞报告工具
|
||||
│ │
|
||||
│ ├── knowledge/ # 专业知识模块
|
||||
│ │ ├── vulnerabilities/ # 漏洞类型知识
|
||||
│ │ └── frameworks/ # 框架安全知识
|
||||
│ │
|
||||
│ └── agents/
|
||||
│ ├── base.py # Agent 基类
|
||||
│ ├── orchestrator.py # 编排 Agent
|
||||
│ ├── analysis.py # 分析 Agent
|
||||
│ └── verification.py # 验证 Agent
|
||||
|
||||
backend/app/models/
|
||||
└── agent_task.py # 🔄 新增 AgentCheckpoint, AgentTreeNode
|
||||
|
||||
backend/app/api/v1/endpoints/
|
||||
└── agent_tasks.py # 🔄 新增 Agent 树和检查点 API
|
||||
|
||||
backend/alembic/versions/
|
||||
└── 007_add_agent_checkpoint_tables.py # 🆕 数据库迁移
|
||||
|
||||
frontend/src/shared/api/
|
||||
└── agentTasks.ts # 🔄 扩展 Agent 树和检查点 API
|
||||
|
||||
frontend/src/pages/
|
||||
└── AgentAudit.tsx # 🆕 统一的 Agent 审计页面 (Strix-inspired)
|
||||
|
||||
frontend/src/app/
|
||||
└── routes.tsx # 🔄 新增 Agent 审计路由
|
||||
|
||||
frontend/src/components/layout/
|
||||
└── Sidebar.tsx # 🔄 新增 Agent 审计导航图标
|
||||
```
|
||||
|
||||
### 下一步计划
|
||||
|
||||
1. 测试前端页面渲染和流式事件
|
||||
2. 知识模块选择 UI
|
||||
3. 检查点恢复功能
|
||||
Loading…
Reference in New Issue