Compare commits

..
47 Commits
Author SHA1 Message Date
公明andGitHub b74b882855 Add files via upload 2026-07-08 15:24:51 +08:00
公明andGitHub 5c4e8cdfb3 Add files via upload 2026-07-08 15:22:36 +08:00
公明andGitHub 62fafbf09b Add files via upload 2026-07-08 15:20:59 +08:00
公明andGitHub 784be8a162 Add files via upload 2026-07-08 15:17:06 +08:00
公明andGitHub c2a1d6c632 Add files via upload 2026-07-08 14:39:50 +08:00
公明andGitHub 2980d17dc7 Add files via upload 2026-07-08 14:39:30 +08:00
公明andGitHub a59084b8ae Add files via upload 2026-07-08 14:21:10 +08:00
公明andGitHub 28214254b5 Add files via upload 2026-07-08 14:19:04 +08:00
公明andGitHub a5d26db5c0 Add files via upload 2026-07-08 13:51:05 +08:00
公明andGitHub b4b21f57fe Add files via upload 2026-07-08 10:55:34 +08:00
公明andGitHub 89264c9c1a Add files via upload 2026-07-08 10:31:32 +08:00
公明andGitHub dc541b91b5 Add files via upload 2026-07-07 18:24:30 +08:00
公明andGitHub cd5448c56d Add files via upload 2026-07-07 17:49:58 +08:00
公明andGitHub 9464cb3690 Add files via upload 2026-07-07 17:49:48 +08:00
公明andGitHub 2db9831b2f Add files via upload 2026-07-07 17:40:45 +08:00
公明andGitHub 8a10370b4e Add files via upload 2026-07-07 17:38:31 +08:00
公明andGitHub 8c2808c65a Add files via upload 2026-07-07 17:35:08 +08:00
公明andGitHub eb542e38f5 Add files via upload 2026-07-07 17:29:20 +08:00
公明andGitHub 95e00563da Add files via upload 2026-07-07 17:29:11 +08:00
公明andGitHub dd4c22a1bd Add files via upload 2026-07-07 17:17:19 +08:00
公明andGitHub 8ef47474ff Add files via upload 2026-07-07 17:01:38 +08:00
公明andGitHub 62049e18d0 Add files via upload 2026-07-07 16:59:13 +08:00
公明andGitHub c0b446226b Add files via upload 2026-07-07 16:53:36 +08:00
公明andGitHub cca6796176 Add files via upload 2026-07-07 16:32:15 +08:00
公明andGitHub 741f131f80 Add files via upload 2026-07-07 16:08:38 +08:00
公明andGitHub 9712ff9311 Add files via upload 2026-07-07 15:09:04 +08:00
公明andGitHub a678d47efc Add files via upload 2026-07-07 14:53:38 +08:00
公明andGitHub 8bc137882b Add files via upload 2026-07-07 14:45:07 +08:00
公明andGitHub b52f8990f3 Add files via upload 2026-07-07 14:32:42 +08:00
公明andGitHub cdd1894737 Add files via upload 2026-07-07 14:20:55 +08:00
公明andGitHub caf4cf61c1 Add files via upload 2026-07-07 14:06:29 +08:00
公明andGitHub 00802a275c Add files via upload 2026-07-07 14:04:18 +08:00
公明andGitHub 3dfcde7c88 Delete docs directory 2026-07-07 14:02:14 +08:00
公明andGitHub 60ba6b8eb3 Add files via upload 2026-07-07 11:48:53 +08:00
公明andGitHub 4408fe6024 Add files via upload 2026-07-07 11:43:18 +08:00
公明andGitHub 92db33cbf2 Add files via upload 2026-07-07 11:42:31 +08:00
公明andGitHub d2390f841f Add files via upload 2026-07-07 11:41:08 +08:00
公明andGitHub dc5791f85c Add files via upload 2026-07-07 11:39:05 +08:00
公明andGitHub 45e5c1bf39 Add files via upload 2026-07-07 11:36:21 +08:00
公明andGitHub 87c9d79f7a Add files via upload 2026-07-07 11:35:16 +08:00
公明andGitHub bb4f239358 Add files via upload 2026-07-07 11:33:22 +08:00
公明andGitHub 84cbaa57dc Add files via upload 2026-07-07 11:31:38 +08:00
公明andGitHub 6dffa64513 Add files via upload 2026-07-07 11:17:15 +08:00
公明andGitHub e88b28c8bd Add files via upload 2026-07-07 11:07:34 +08:00
公明andGitHub c84612211c Add files via upload 2026-07-07 10:17:03 +08:00
公明andGitHub d2bd59ced7 Add files via upload 2026-07-06 18:03:31 +08:00
公明andGitHub 8393b3a7a6 Add files via upload 2026-07-06 18:00:37 +08:00
158 changed files with 17423 additions and 501 deletions
+37 -20
View File
@@ -9,6 +9,12 @@
**Community**: [Join us on Discord](https://discord.gg/8PjVCMu8Zw)
**CyberStrikeAI is building the agentic execution layer for modern cyber security.**
It brings AI agents, security tools, MCP-native integrations, knowledge systems, human oversight, and attack-chain intelligence into a unified workspace for authorized cyber engagements. Instead of treating tools, prompts, evidence, approvals, and reports as separate fragments, CyberStrikeAI turns security intent into auditable multi-agent workflows that can plan, execute, review, replay, and continuously accumulate operational context.
Built in Go, CyberStrikeAI provides a full-stack foundation for AI-native security operations: 100+ curated tool recipes, role-based testing, Agent Skills, Eino-powered single-agent and multi-agent orchestration, RAG knowledge retrieval, graph workflows, vulnerability and task lifecycle management, WebShell operations, chatbot access, and a lightweight built-in C2 framework for authorized lab and engagement scenarios.
<details>
<summary><strong>WeChat group</strong> (click to reveal QR code)</summary>
@@ -27,8 +33,6 @@ If CyberStrikeAI helps you, you can support the project via **WeChat Pay** or **
</details>
CyberStrikeAI is an **AI-native security testing platform** built in Go. It integrates 100+ security tools, an intelligent orchestration engine, role-based testing with predefined security roles, a skills system with specialized testing skills, comprehensive lifecycle management capabilities, and a **built-in lightweight C2 (Command & Control) framework** for **authorized** engagements (listeners, encrypted implants, sessions, tasks, real-time events, REST and MCP). Through native MCP protocol and AI agents, it enables end-to-end automation from conversational commands to vulnerability discovery, attack-chain analysis, knowledge retrieval, and result visualization—delivering an auditable, traceable, and collaborative testing environment for security teams.
## Interface & Integration Preview
<div align="center">
@@ -115,24 +119,26 @@ CyberStrikeAI is an **AI-native security testing platform** built in Go. It inte
## Highlights
- 🤖 AI decision engine with OpenAI-compatible models (GPT, Claude, DeepSeek, etc.)
- 🔌 Native MCP implementation with HTTP/stdio/SSE transports and external MCP federation
- 🧰 100+ prebuilt tool recipes + YAML-based extension system
- 🤖 Agentic execution layer for translating natural-language intent into precise, governed, auditable security action
- 🧩 Eino-powered single-agent and multi-agent orchestration with Deep, Plan-Execute, and Supervisor modes
- 🔌 MCP-native tool execution with HTTP/stdio/SSE transports, external MCP federation, and dynamic tool discovery
- 🧰 100+ curated security tool recipes, YAML-based extensions, and role-scoped tool control
- 📄 Large-result pagination, compression, and searchable archives
- 🔗 Attack-chain graph, risk scoring, and step-by-step replay
- 🔒 Password-protected web UI, audit logs, and SQLite persistence
- 🔗 Attack-chain intelligence with graph views, risk scoring, project facts, and step-by-step replay
- 🧑‍⚖️ Human-in-the-loop governance with approval modes, allowlists, audit-agent review, and traceable decisions
- 🔒 Password-protected web UI, audit logs, SQLite persistence, and operational evidence retention
- 📚 Knowledge base (RAG): **Eino MultiQuery** query rewrite + multi-path vector retrieval + **HTTP rerank** (DashScope `gte-rerank` / Cohere-compatible) + post-processing (dedupe, budget); **Eino Compose** indexing pipeline
- 📁 Conversation grouping with pinning, rename, and batch management
- 📂 **Project management**: shared facts (blackboard) across sessions, `upsert_project_fact` + `links` to chain paths; attack-chain and project fact graph views
- 🛡️ Vulnerability management with CRUD operations, severity tracking, status workflow, and statistics
- 📋 Batch task management: create task queues, add multiple tasks, and execute them sequentially
- 🎭 Role-based testing: predefined security testing roles (Penetration Testing, CTF, Web App Scanning, etc.) with custom prompts and tool restrictions
- 🔀 **Graph orchestration**: visual workflow editor (Start / Agent / Tool / Condition / HITL / Output) with `{{previous.output}}` and `{{outputs.variable_name}}` for inter-node data passing; bind a graph to a role for automatic execution on chat. See [Graph orchestration guide](docs/workflow-graph_en.md)
- 🧩 **Agent orchestration (CloudWeGo Eino)**: **single-agent** via **`/api/eino-agent/stream`** (Eino ADK `ChatModelAgent`); **multi-agent** via **`/api/multi-agent/stream`** with **`deep`** (coordinator + `task` sub-agents), **`plan_execute`**, or **`supervisor`** (`orchestration` in the request body). ADK **summarization** compresses long contexts; pre-compaction **transcripts** land at `data/conversation_artifacts/<conversation-id>/summarization/transcript.txt` (full user/assistant/tool turns; static system omitted). Markdown under `agents/`: `orchestrator.md`, `orchestrator-plan-execute.md`, `orchestrator-supervisor.md`, plus sub-agent `*.md` (see [Multi-agent doc](docs/MULTI_AGENT_EINO.md))
- 🖼️ **Vision analysis (`analyze_image`)**: separate VL model (e.g. `qwen-vl-max`) via MCP for local screenshots, captchas, and UI; image bytes stay out of agent history (text summaries only). Configure `vision` in `config.yaml`; see [docs/VISION.md](docs/VISION.md)
- 🔀 **Graph orchestration**: visual workflow editor (Start / Agent / Tool / Condition / HITL / Output) with `{{previous.output}}` and `{{outputs.variable_name}}` for inter-node data passing; bind a graph to a role for automatic execution on chat. See [Graph orchestration guide](docs/en-US/workflow-graph.md)
- 🧩 **Agent orchestration (CloudWeGo Eino)**: **single-agent** via **`/api/eino-agent/stream`** (Eino ADK `ChatModelAgent`); **multi-agent** via **`/api/multi-agent/stream`** with **`deep`** (coordinator + `task` sub-agents), **`plan_execute`**, or **`supervisor`** (`orchestration` in the request body). ADK **summarization** compresses long contexts; pre-compaction **transcripts** land at `data/conversation_artifacts/<conversation-id>/summarization/transcript.txt` (full user/assistant/tool turns; static system omitted). Markdown under `agents/`: `orchestrator.md`, `orchestrator-plan-execute.md`, `orchestrator-supervisor.md`, plus sub-agent `*.md` (see [Multi-agent doc](docs/en-US/MULTI_AGENT_EINO.md))
- 🖼️ **Vision analysis (`analyze_image`)**: separate VL model (e.g. `qwen-vl-max`) via MCP for local screenshots, captchas, and UI; image bytes stay out of agent history (text summaries only). Configure `vision` in `config.yaml`; see [docs/en-US/VISION.md](docs/en-US/VISION.md)
- 🎯 **Skills (refactored for Eino)**: packs under `skills_dir` follow **Agent Skills** layout (`SKILL.md` + optional files); **multi-agent** sessions use the official Eino ADK **`skill`** tool for **progressive disclosure** (load by name), with optional **host filesystem / shell** via `multi_agent.eino_skills`; optional **`eino_middleware`** adds patchtoolcalls, tool_search, **plantask** (`TaskCreate` / `TaskList` boards under `skills_dir/.eino/plantask/`), reduction, file **checkpoints** (`checkpoint_dir`), ChatModel **retries**, session **output key**, and Deep tuning—20+ sample domains (SQLi, XSS, API security, …) ship under `skills/`
- 📱 **Chatbot**: Personal WeChat, WeCom, DingTalk, Lark, Telegram, Slack, Discord, and QQ Bot—chat from mobile or IM apps (see [Robot / Chatbot guide](docs/robot_en.md))
- 🧑‍⚖️ **Human-in-the-loop (HITL)**: Chat sidebar to set approval mode and tool allowlists (listed tools skip approval); global list in `config.yaml` under `hitl.tool_whitelist`; **Apply** can merge new tools into the file and update the running server without restart; dedicated **HITL** page for pending approvals
- 📱 **Chatbot**: Personal WeChat, WeCom, DingTalk, Lark, Telegram, Slack, Discord, and QQ Bot—chat from mobile or IM apps (see [Robot / Chatbot guide](docs/en-US/robot.md))
- 🧑‍⚖️ **Human-in-the-loop (HITL)**: Chat sidebar to set approval mode and tool allowlists (listed tools skip approval); global list in `config.yaml` under `hitl.tool_whitelist`; the Audit Agent can use a separate lightweight model via `hitl.audit_model`; **Apply** can merge new tools into the file and update the running server without restart; dedicated **HITL** page for pending approvals. See [HITL best practices](docs/en-US/hitl-best-practices.md)
- 🐚 **WebShell management**: Add and manage WebShell connections (e.g. IceSword/AntSword compatible), use a virtual terminal for command execution, a built-in file manager for file operations, and an AI assistant tab that orchestrates tests and keeps per-connection conversation history; supports PHP, ASP, ASPX, JSP and custom shell types with configurable request method and command parameter.
- 📡 **Built-in C2**: AI-oriented lightweight command-and-control—**listeners** (TCP reverse, HTTP/HTTPS beacon, WebSocket), **encrypted** beacon channel, **session** and **task** queues with persistence, **payload** helpers (one-liner / build / download), **SSE** live events, REST under `/api/c2/*`, plus unified MCP tools (`c2_listener`, `c2_session`, **`c2_task`**, `c2_task_manage`, `c2_payload`, `c2_event`, `c2_profile`, `c2_file`); optional **HITL** approval for sensitive operations and OPSEC-style controls (e.g. command deny rules). **Authorized testing only.**
@@ -256,7 +262,7 @@ Requirements / tips:
- **Conversation testing** Natural-language prompts trigger toolchains with streaming SSE output.
- **Single vs multi-agent** Chat UI switches between **Eino single-agent** (`/api/eino-agent/stream`) and **multi-agent** (`/api/multi-agent/stream` with `orchestration`: `deep` | `plan_execute` | `supervisor`). Multi mode requires `multi_agent.enabled: true`. MCP tools are bridged the same way for both paths.
- **Role-based testing** Select from predefined security testing roles (Penetration Testing, CTF, Web App Scanning, API Security Testing, etc.) to customize AI behavior and tool availability. Each role applies custom system prompts and can restrict available tools for focused testing scenarios.
- **Graph orchestration** Design flows on the **Graph Orchestration** page (drag nodes, connect edges, save); bind `workflow_id` on a role to run the graph on chat (Agent, MCP tools, condition branches). Use `{{outputs.variable_name}}` to pass data across non-adjacent nodes. See [Graph orchestration guide](docs/workflow-graph_en.md).
- **Graph orchestration** Design flows on the **Graph Orchestration** page (drag nodes, connect edges, save); bind `workflow_id` on a role to run the graph on chat (Agent, MCP tools, condition branches). Use `{{outputs.variable_name}}` to pass data across non-adjacent nodes. See [Graph orchestration guide](docs/en-US/workflow-graph.md).
- **Tool monitor** Inspect running jobs, execution logs, and large-result attachments.
- **History & audit** Every conversation and tool invocation is stored in SQLite with replay.
- **Conversation groups** Organize conversations into groups, pin important groups, rename or delete groups via context menu.
@@ -265,7 +271,7 @@ Requirements / tips:
- **WebShell management** Add and manage WebShell connections (PHP/ASP/ASPX/JSP or custom). Use the virtual terminal to run commands, the file manager to list, read, edit, upload, and delete files, and the AI assistant tab to drive scripted tests with per-connection conversation history. Connections are stored in SQLite; supports GET/POST and configurable command parameter (e.g. IceSword/AntSword style).
- **Built-in C2** Create/start **listeners**, generate **payloads**, track **sessions**, enqueue **tasks**, and subscribe to **events** (SSE) from the Web UI or `/api/c2/*`. Agents and external clients use the C2 MCP tool family (including **`c2_task`**); when HITL is enabled, high-risk tasks can require human approval. Intended **only** for systems you are explicitly authorized to test.
- **Settings** Tweak provider keys, MCP enablement, tool toggles, and agent iteration limits.
- **Human-in-the-loop (HITL)** Sidebar sets mode and allowlisted tools (comma- or newline-separated); global list lives in `config.yaml` under `hitl.tool_whitelist`. **Apply** updates browser/server and can merge new tools into the file (**no restart**). **New chat** keeps sidebar choices; **HITL** nav shows pending approvals. Removing a tool in the sidebar does not remove it from the global list in `config.yaml`—edit the file if needed.
- **Human-in-the-loop (HITL)** Sidebar sets mode and allowlisted tools (comma- or newline-separated); global list lives in `config.yaml` under `hitl.tool_whitelist`. The Audit Agent can use a separate low-cost model through `hitl.audit_model`, useful when human reviewers cannot keep up. **Apply** updates browser/server and can merge new tools into the file (**no restart**). **New chat** keeps sidebar choices; **HITL** nav shows pending approvals. Removing a tool in the sidebar does not remove it from the global list in `config.yaml`—edit the file if needed.
### Built-in Safeguards
- Required-field validation prevents accidental blank API credentials.
@@ -308,7 +314,7 @@ Requirements / tips:
- **Management** Web UI: **Agents → Agent management**; API `/api/multi-agent/markdown-agents`.
- **Config** `multi_agent` in `config.yaml`: `enabled`, `robot_default_agent_mode`, `batch_use_multi_agent`, `max_iteration`, `plan_execute_loop_max_iterations`, per-mode orchestrator instruction fields, optional YAML `sub_agents` merged with disk (`id` clash → Markdown wins), **`eino_skills`**, **`eino_middleware`** (optional ADK middleware and Deep/Supervisor tuning).
- **Resilience & long runs** `checkpoint_dir` enables ADK **resume** after process crashes (distinct from trace-based “interrupt & continue”). `deep_model_retry_max_retries` retries transient LLM API failures within a single call. **Summarization** writes a filtered **transcript** when compression fires; the summary message includes the path so the model can `read_file` for scan output and other pre-compaction details.
- **Details** **[docs/MULTI_AGENT_EINO.md](docs/MULTI_AGENT_EINO.md)** (streaming, robots, batch, middleware caveats).
- **Details** **[docs/en-US/MULTI_AGENT_EINO.md](docs/en-US/MULTI_AGENT_EINO.md)** (streaming, robots, batch, middleware caveats).
### Skills System (Agent Skills + Eino)
- **Layout** Each skill is a directory with **required** `SKILL.md` only ([Agent Skills](https://platform.claude.com/docs/en/agents-and-tools/agent-skills/overview)): YAML front matter **only** `name` and `description`, plus Markdown body. Optional sibling files (`FORMS.md`, `REFERENCE.md`, `scripts/*`, …). **No** `SKILL.yaml` (not part of Claude or Eino specs); sections/scripts/progressive behavior are **derived at runtime** from Markdown and the filesystem.
@@ -329,7 +335,7 @@ Requirements / tips:
- **Result compression** multi-megabyte logs can be summarized or losslessly compressed before persisting to keep SQLite lean.
**Creating a custom tool (typical flow)**
1. Copy an existing YAML file from `tools/` (for example `tools/sample.yaml`).
1. Copy an existing YAML file from `tools/` (for example `tools/nmap.yaml` or `tools/ffuf.yaml`).
2. Update `name`, `command`, `args`, and `short_description`.
3. Describe positional or flag parameters in `parameters[]` so the agent knows how to build CLI arguments.
4. Provide a longer `description`/`notes` block if the agent needs extra context or post-processing tips.
@@ -631,9 +637,18 @@ enabled: true
## Related documentation
- [Multi-agent mode (Eino)](docs/MULTI_AGENT_EINO.md): **Deep**, **Plan-Execute**, **Supervisor**, `agents/*.md`, `eino_skills` / `eino_middleware`, APIs, and chat/stream behavior.
- [Graph orchestration guide](docs/workflow-graph_en.md): visual workflow design, node configuration, `previous` / `outputs` variable passing, and role binding.
- [Robot / Chatbot guide](docs/robot_en.md): Setup, commands, and troubleshooting for WeChat, WeCom, DingTalk, Lark, Telegram, Slack, Discord, and QQ Bot.
- [Documentation index](docs/README.md): deployment, configuration, security model, API, knowledge base, C2, WebShell, MCP, development, testing, and troubleshooting.
- [Deployment guide](docs/en-US/deployment.md): source/binary startup, HTTPS, reverse proxy, systemd, backup, upgrade, and rollback.
- [Runbooks](docs/en-US/runbooks.md): production setup, external MCP, knowledge base, authorized Web testing, and C2 cleanup workflows.
- [Security hardening](docs/en-US/security-hardening.md): launch baseline, HITL allowlist, reverse proxy, file permissions, and periodic review.
- [API recipes](docs/en-US/api-recipes.md): examples for login, Agent, streaming, multi-agent, uploads, vulnerabilities, KB, and audit export.
- [Configuration reference](docs/en-US/configuration.md): main `config.yaml` sections, recommended values, and update guidance.
- [Security model](docs/en-US/security-model.md): authentication, tool execution, HITL, audit, C2/WebShell, and data safety boundaries.
- [API reference](docs/en-US/api-reference.md): OpenAPI, authentication, Agent, projects, knowledge base, C2, WebShell, and other API entry points.
- [Multi-agent mode (Eino)](docs/en-US/MULTI_AGENT_EINO.md): **Deep**, **Plan-Execute**, **Supervisor**, `agents/*.md`, `eino_skills` / `eino_middleware`, APIs, and chat/stream behavior.
- [Graph orchestration guide](docs/en-US/workflow-graph.md): visual workflow design, node configuration, `previous` / `outputs` variable passing, and role binding.
- [Robot / Chatbot guide](docs/en-US/robot.md): Setup, commands, and troubleshooting for WeChat, WeCom, DingTalk, Lark, Telegram, Slack, Discord, and QQ Bot.
- [HITL best practices](docs/en-US/hitl-best-practices.md): reviewer modes, allowlists, Audit Agent prompts, and separate small-model configuration.
## Project Layout
@@ -646,7 +661,7 @@ CyberStrikeAI/
├── roles/ # Role configurations (12+ predefined security testing roles)
├── skills/ # Agent Skills dirs (SKILL.md + optional files; demo: cyberstrike-eino-demo)
├── agents/ # Multi-agent Markdown (orchestrator.md + sub-agent *.md)
├── docs/ # Documentation (e.g. robot/chatbot guide, MULTI_AGENT_EINO.md)
├── docs/ # Topic docs (deployment, config, security, API, knowledge base, C2, WebShell, etc.)
├── images/ # Docs screenshots & diagrams
├── config.yaml # Runtime configuration
├── run.sh # Convenience launcher
@@ -710,6 +725,8 @@ CyberStrikeAI is a professional security testing platform designed to assist sec
**The developers are not responsible for any misuse!** Please ensure your usage complies with local laws and regulations, and that you have obtained explicit authorization from the target system owner.
For vulnerability reporting and deployment hardening guidance, see [SECURITY.md](SECURITY.md).
---
Need help or want to contribute? Open an issue or PR—community tooling additions are welcome!
+37 -20
View File
@@ -8,6 +8,12 @@
**社区**[加入 Discord](https://discord.gg/8PjVCMu8Zw)
**CyberStrikeAI 正在构建现代网络安全的智能体执行层。**
它将 AI 智能体、安全工具、MCP 原生集成、知识系统、人工监督与攻击链智能汇聚到一个面向授权安全任务的统一工作空间中。CyberStrikeAI 不再把工具、提示词、证据、审批和报告视为割裂环节,而是将安全意图转化为可规划、可执行、可审查、可复盘、可持续沉淀上下文的多智能体工作流。
CyberStrikeAI 基于 Go 构建,为 AI 原生安全运营提供完整底座:100+ 精选工具配方、角色化测试、Agent Skills、基于 Eino 的单智能体与多智能体编排、RAG 知识检索、图工作流、漏洞与任务生命周期管理、WebShell 运营、机器人接入,以及面向授权实验室和安全任务场景的内置轻量 C2 框架。
<details>
<summary><strong>微信群</strong>(点击展开二维码)</summary>
@@ -26,8 +32,6 @@
</details>
CyberStrikeAI 是一款 **AI 原生安全测试平台**,基于 Go 构建,集成了 100+ 安全工具、智能编排引擎、角色化测试与预设安全测试角色、Skills 技能系统与专业测试技能、完整的测试生命周期管理能力,以及面向 **授权场景****内置轻量 C2Command & Control,指挥与控制)** 能力(监听器、加密通信、会话与任务、实时事件、REST 与 MCP 协同)。通过原生 MCP 协议与 AI 智能体,支持从对话指令到漏洞发现、攻击链分析、知识检索与结果可视化的全流程自动化,为安全团队提供可审计、可追溯、可协作的专业测试环境。
## 界面与集成预览
<div align="center">
@@ -114,24 +118,26 @@ CyberStrikeAI 是一款 **AI 原生安全测试平台**,基于 Go 构建,集
## 特性速览
- 🤖 兼容 OpenAI/DeepSeek/Claude 等模型的智能决策引擎
- 🔌 原生 MCP 协议,支持 HTTP / stdio / SSE 传输模式以及外部 MCP 接入
- 🧰 100+ 现成工具模版 + YAML 扩展能力
- 🤖 面向智能体时代的执行层,将自然语言意图转化为精准、受控、可审计的安全行动
- 🧩 基于 Eino 的单智能体与多智能体编排,支持 Deep、Plan-Execute、Supervisor 等模式
- 🔌 MCP 原生工具执行,支持 HTTP / stdio / SSE 传输、外部 MCP 联邦与动态工具发现
- 🧰 100+ 精选安全工具配方、YAML 扩展机制与按角色收敛的工具控制
- 📄 大结果分页、压缩与全文检索
- 🔗 攻击链可视化、风险打分与步骤回放
- 🔒 Web 登录保护、审计日志、SQLite 持久化
- 🔗 攻击链智能分析,支持图谱视图、风险打分、项目事实沉淀与步骤回放
- 🧑‍⚖️ 人机协同治理,支持审批模式、免审批白名单、审计 Agent 复核与可追溯决策
- 🔒 Web 登录保护、审计日志、SQLite 持久化与行动证据留存
- 📚 知识库(RAG):**Eino MultiQuery** 查询改写 + 多路向量检索 + **HTTP 精排**DashScope `gte-rerank` / Cohere 兼容)+ 后处理(去重、预算);索引侧为 **Eino Compose** 流水线
- 📁 对话分组管理:支持分组创建、置顶、重命名、删除等操作
- 📂 **项目管理**:共享事实(黑板)跨会话沉淀认知,`upsert_project_fact` + `links` 串联攻击路径;聊天攻击链与项目事实图可视化
- 🛡️ 漏洞管理功能:完整的漏洞 CRUD 操作,支持严重程度分级、状态流转、按对话/严重程度/状态过滤,以及统计看板
- 📋 批量任务管理:创建任务队列,批量添加任务,依次顺序执行,支持任务编辑与状态跟踪
- 🎭 角色化测试:预设安全测试角色(渗透测试、CTF、Web 应用扫描等),支持自定义提示词和工具限制
- 🔀 **图编排**:可视化流程编排(开始 / Agent / 工具 / 条件 / 审批 / 输出),节点间用 `{{previous.output}}``{{outputs.变量名}}` 传参;绑定角色后对话自动按图执行。详见 [图编排使用说明](docs/workflow-graph.md)
- 🧩 **Agent 编排(CloudWeGo Eino****单代理** `POST /api/eino-agent/stream`Eino ADK);**多代理** `POST /api/multi-agent/stream``orchestration`**`deep`** / **`plan_execute`** / **`supervisor`**。ADK **Summarization** 在上下文过长时压缩历史;压缩前将可恢复 **转录** 写入 `data/conversation_artifacts/<会话ID>/summarization/transcript.txt`(保留完整 user/assistant/tool 轮次,省略静态 system)。`agents/` 下主代理与子代理 Markdown 见 [多代理说明](docs/MULTI_AGENT_EINO.md)
- 🖼️ **视觉分析(`analyze_image`**:独立 Vision 模型(如 `qwen-vl-max`),MCP 工具分析本地截图/验证码/UI;图片仅在单次 VL 调用中出现,对话上下文只保留文字摘要。配置见 `config.yaml``vision` 与 [视觉分析说明](docs/VISION.md)
- 🔀 **图编排**:可视化流程编排(开始 / Agent / 工具 / 条件 / 审批 / 输出),节点间用 `{{previous.output}}``{{outputs.变量名}}` 传参;绑定角色后对话自动按图执行。详见 [图编排使用说明](docs/zh-CN/workflow-graph.md)
- 🧩 **Agent 编排(CloudWeGo Eino****单代理** `POST /api/eino-agent/stream`Eino ADK);**多代理** `POST /api/multi-agent/stream``orchestration`**`deep`** / **`plan_execute`** / **`supervisor`**。ADK **Summarization** 在上下文过长时压缩历史;压缩前将可恢复 **转录** 写入 `data/conversation_artifacts/<会话ID>/summarization/transcript.txt`(保留完整 user/assistant/tool 轮次,省略静态 system)。`agents/` 下主代理与子代理 Markdown 见 [多代理说明](docs/zh-CN/MULTI_AGENT_EINO.md)
- 🖼️ **视觉分析(`analyze_image`**:独立 Vision 模型(如 `qwen-vl-max`),MCP 工具分析本地截图/验证码/UI;图片仅在单次 VL 调用中出现,对话上下文只保留文字摘要。配置见 `config.yaml``vision` 与 [视觉分析说明](docs/zh-CN/VISION.md)
- 🎯 **Skills(面向 Eino 重构)**:技能包放在 **`skills_dir`**,遵循 **Agent Skills** 目录规范(`SKILL.md` + 可选文件);**多代理** 下通过 Eino 官方 **`skill`** 工具 **渐进式披露**(按 name 加载)。**`multi_agent.eino_skills`** 控制是否启用、本机文件/Shell 工具、工具名覆盖;**`eino_middleware`** 可选 patch、tool_search、**plantask**`TaskCreate` / `TaskList` 任务板,落在 `skills_dir/.eino/plantask/`)、reduction、文件型 **checkpoint**`checkpoint_dir`)、ChatModel **重试**、会话 **输出键** 及 Deep 调参。20+ 领域示例仍可绑定角色
- 📱 **机器人**:个人微信、企业微信、钉钉、飞书、Telegram、Slack、Discord、QQ 机器人,在手机或 IM 中与 CyberStrikeAI 对话(详见 [机器人使用说明](docs/robot.md)
- 🧑‍⚖️ **人机协同(HITL**:对话页侧栏配置协同模式与免审批工具白名单;全局列表在 `config.yaml``hitl.tool_whitelist`;点「应用」可将新增工具合并写入配置文件且**无需重启**即可生效;导航 **人机协同** 页处理待审批工具调用
- 📱 **机器人**:个人微信、企业微信、钉钉、飞书、Telegram、Slack、Discord、QQ 机器人,在手机或 IM 中与 CyberStrikeAI 对话(详见 [机器人使用说明](docs/zh-CN/robot.md)
- 🧑‍⚖️ **人机协同(HITL**:对话页侧栏配置协同模式与免审批工具白名单;全局列表在 `config.yaml``hitl.tool_whitelist`审计 Agent 可通过 `hitl.audit_model` 使用独立小模型;点「应用」可将新增工具合并写入配置文件且**无需重启**即可生效;导航 **人机协同** 页处理待审批工具调用。详见 [人机协同最佳实践](docs/zh-CN/hitl-best-practices.md)
- 🐚 **WebShell 管理**:添加与管理 WebShell 连接(兼容冰蝎/蚁剑等),通过虚拟终端执行命令、内置文件管理进行文件操作,并提供按连接维度保存历史的 AI 助手标签页;支持 PHP/ASP/ASPX/JSP 及自定义类型,可配置请求方法与命令参数。
- 📡 **内置 C2**:面向 AI 协同的轻量 **C2**——**多种监听器**TCP 反向、HTTP/HTTPS Beacon、WebSocket)、**加密** Beacon 信道、**会话与任务**队列及持久化、**Payload** 辅助(一键命令 / 构建 / 下载)、**SSE** 实时事件、REST`/api/c2/*`)及智能体侧 **一组 C2 MCP 工具**(如 `c2_listener``c2_session`、**`c2_task`**、`c2_task_manage``c2_payload``c2_event``c2_profile``c2_file`);敏感操作可对接 **人机协同(HITL**,并支持 OPSEC 类规则(如命令拒绝正则)。**仅限授权测试。**
@@ -254,7 +260,7 @@ go build -o cyberstrike-ai cmd/server/main.go
- **对话测试**:自然语言触发多步工具编排,SSE 实时输出。
- **单代理 / 多代理**:聊天可选 **Eino 单代理**`/api/eino-agent/stream`)与 **多代理**`/api/multi-agent/stream` + `orchestration`)。多代理需 `multi_agent.enabled: true`。MCP 工具桥接一致。
- **角色化测试**:从预设的安全测试角色(渗透测试、CTF、Web 应用扫描、API 安全测试等)中选择,自定义 AI 行为和可用工具。每个角色可应用自定义系统提示词,并可限制可用工具列表,实现聚焦的测试场景。
- **图编排**:在 **图编排** 页拖拽节点、连线并保存流程;在角色中绑定 `workflow_id` 后,该角色对话将按图执行(Agent、MCP 工具、条件分支等)。跨节点传参优先用 `{{outputs.变量名}}`。详见 [图编排使用说明](docs/workflow-graph.md)。
- **图编排**:在 **图编排** 页拖拽节点、连线并保存流程;在角色中绑定 `workflow_id` 后,该角色对话将按图执行(Agent、MCP 工具、条件分支等)。跨节点传参优先用 `{{outputs.变量名}}`。详见 [图编排使用说明](docs/zh-CN/workflow-graph.md)。
- **工具监控**:查看任务队列、执行日志、大文件附件。
- **会话历史**:所有对话与工具调用保存在 SQLite,可随时重放。
- **对话分组**:将对话按项目或主题组织到不同分组,支持置顶、重命名、删除等操作,所有数据持久化存储。
@@ -263,7 +269,7 @@ go build -o cyberstrike-ai cmd/server/main.go
- **WebShell 管理**:添加并管理 WebShell 连接(PHP/ASP/ASPX/JSP 或自定义类型)。使用虚拟终端执行命令(带命令历史与快捷命令),使用文件管理浏览、读取、编辑、上传与删除目标文件,并支持按路径导航和名称过滤。连接信息持久化存储于 SQLite,支持 GET/POST 及可配置命令参数(兼容冰蝎/蚁剑等)。
- **内置 C2**:在 Web 界面或 `/api/c2/*` 创建/启动 **监听器**、生成 **Payload**、查看 **会话**、下发 **任务** 并订阅 **事件(SSE)**。智能体与外部客户端通过 **C2 MCP 工具族**(含 **`c2_task`** 等)编排;开启人机协同时,高风险任务可走审批。**仅用于已获明确授权的目标。**
- **可视化配置**:在界面中切换模型、启停工具、设置迭代次数等。
- **人机协同(HITL)**:侧栏设置协同模式与免审批工具(逗号或换行);全局白名单见 `config.yaml` 的 `hitl.tool_whitelist`。点「**应用**」可写浏览器/服务端并合并新增工具进配置(**无需重启**)。**新对话**保留侧栏选择;导航 **人机协同** 处理待审批。从侧栏删掉工具不会自动从配置文件移除全局项,需手改 `config.yaml`。
- **人机协同(HITL)**:侧栏设置协同模式与免审批工具(逗号或换行);全局白名单见 `config.yaml` 的 `hitl.tool_whitelist`。审计 Agent 可通过 `hitl.audit_model` 单独配置低成本模型,适合人工审计压力较大时接管常规审批。点「**应用**」可写浏览器/服务端并合并新增工具进配置(**无需重启**)。**新对话**保留侧栏选择;导航 **人机协同** 处理待审批。从侧栏删掉工具不会自动从配置文件移除全局项,需手改 `config.yaml`。
### 默认安全措施
- 设置面板内置必填校验,防止漏配 API Key/Base URL/模型。
@@ -306,7 +312,7 @@ go build -o cyberstrike-ai cmd/server/main.go
- **界面管理****Agents → Agent 管理**API `/api/multi-agent/markdown-agents`。
- **配置项**`multi_agent``enabled`、`robot_default_agent_mode`、`batch_use_multi_agent`、`max_iteration`、`plan_execute_loop_max_iterations`、各模式 orchestrator 指令字段、可选 YAML `sub_agents` 与目录合并(同 `id` → Markdown 优先)、**`eino_skills`**、**`eino_middleware`**。
- **长任务与恢复**`checkpoint_dir` 支持进程崩溃后 ADK **断点续跑**(与基于 trace 的「中断继续」不同)。`deep_model_retry_max_retries` 在同一次 LLM 调用内重试瞬时 API 失败。**Summarization** 触发压缩时会写入过滤后的 **transcript**,摘要消息中带路径,模型可用 `read_file` 找回扫描输出等压缩前细节。
- **更多细节**[docs/MULTI_AGENT_EINO.md](docs/MULTI_AGENT_EINO.md)(流式、机器人、批量、中间件差异)。
- **更多细节**[docs/zh-CN/MULTI_AGENT_EINO.md](docs/zh-CN/MULTI_AGENT_EINO.md)(流式、机器人、批量、中间件差异)。
### Skills 技能系统(Agent Skills + Eino
- **目录规范**:与 [Agent Skills](https://platform.claude.com/docs/en/agents-and-tools/agent-skills/overview) 一致,**仅**需目录下的 **`SKILL.md`**YAML 头只用官方的 **`name` 与 `description`**,正文为 Markdown。可选同目录其他文件(`FORMS.md`、`REFERENCE.md`、`scripts/*` 等)。**不使用 `SKILL.yaml`**Claude / Eino 官方均无此文件);章节、`scripts/` 列表、渐进式行为由运行时从正文与磁盘 **自动推导**。
@@ -327,7 +333,7 @@ go build -o cyberstrike-ai cmd/server/main.go
- **结果压缩/摘要**:多兆字节日志可先压缩或生成摘要再写入 SQLite,减小档案体积。
**自定义工具的一般步骤**
1. 复制 `tools/` 下现有示例(如 `tools/sample.yaml`)。
1. 复制 `tools/` 下现有示例(如 `tools/nmap.yaml` 或 `tools/ffuf.yaml`)。
2. 修改 `name`、`command`、`args`、`short_description` 等基础信息。
3. 在 `parameters[]` 中声明位置参数或带 flag 的参数,方便智能体自动拼装命令。
4. 视需要补充 `description` 或 `notes`,给 AI 额外上下文或结果解读提示。
@@ -629,9 +635,18 @@ enabled: true
## 相关文档
- [多代理模式(Eino](docs/MULTI_AGENT_EINO.md)**Deep**、**Plan-Execute**、**Supervisor**、`agents/*.md`、`eino_skills` / `eino_middleware`、接口与流式说明
- [图编排使用说明](docs/workflow-graph.md):可视化流程搭建、节点配置、`previous` / `outputs` 变量传参与角色绑定
- [机器人使用说明](docs/robot.md):个人微信、企业微信、钉钉、飞书、Telegram、Slack、Discord、QQ 机器人的配置、命令与排查
- [文档导航](docs/README.md):部署、配置、安全模型、API、知识库、C2、WebShell、MCP、开发、测试、排错等完整专题入口
- [部署指南](docs/zh-CN/deployment.md):源码/二进制运行、HTTPS、反向代理、systemd、备份、升级与回滚
- [运维 Runbooks](docs/zh-CN/runbooks.md):生产部署、外部 MCP、知识库、授权 Web 测试、C2 清理等可执行流程
- [安全加固指南](docs/zh-CN/security-hardening.md):上线前基线、HITL 白名单、反向代理、文件权限和周期巡检。
- [API Recipes](docs/zh-CN/api-recipes.md):登录、Agent、流式、多代理、上传、漏洞、知识库和审计导出调用示例。
- [配置参考](docs/zh-CN/configuration.md)`config.yaml` 各配置段、推荐值和修改建议。
- [安全模型](docs/zh-CN/security-model.md):认证、工具执行、HITL、审计、C2/WebShell 和数据安全边界。
- [API 参考](docs/zh-CN/api-reference.md)OpenAPI、认证、Agent、项目、知识库、C2、WebShell 等接口入口。
- [多代理模式(Eino](docs/zh-CN/MULTI_AGENT_EINO.md)**Deep**、**Plan-Execute**、**Supervisor**、`agents/*.md`、`eino_skills` / `eino_middleware`、接口与流式说明。
- [图编排使用说明](docs/zh-CN/workflow-graph.md):可视化流程搭建、节点配置、`previous` / `outputs` 变量传参与角色绑定。
- [机器人使用说明](docs/zh-CN/robot.md):个人微信、企业微信、钉钉、飞书、Telegram、Slack、Discord、QQ 机器人的配置、命令与排查。
- [人机协同最佳实践](docs/zh-CN/hitl-best-practices.md):审批方模式、白名单、审计 Agent 提示词策略与独立小模型配置。
## 项目结构
@@ -644,7 +659,7 @@ CyberStrikeAI/
├── roles/ # 角色配置文件目录(含 12+ 预设安全测试角色)
├── skills/ # Agent Skills 目录(SKILL.md + 可选文件;示例 cyberstrike-eino-demo
├── agents/ # 多代理 Markdownorchestrator.md + 子代理 *.md
├── docs/ # 说明文档(如机器人使用说明、MULTI_AGENT_EINO.md
├── docs/ # 专题文档(部署、配置、安全、API、知识库、C2、WebShell 等
├── images/ # 文档配图
├── config.yaml # 运行配置
├── run.sh # 启动脚本
@@ -706,6 +721,8 @@ CyberStrikeAI 是一个专业的安全测试平台,旨在帮助安全研究人
**开发者不对任何滥用行为负责!** 请确保您的使用符合当地法律法规,并获得目标系统所有者的明确授权。
安全问题报告与部署加固建议见 [SECURITY.md](SECURITY.md)。
---
欢迎提交 Issue/PR 贡献新的工具模版或优化建议!
+151
View File
@@ -0,0 +1,151 @@
# Security Policy
[中文](#安全政策) | [English](#security-policy)
## Security Policy
CyberStrikeAI is a security testing and automation platform. It can execute tools, call MCP servers, manage WebShell connections, and optionally run C2 workflows. Please treat every deployment as a high-privilege security system.
### Supported Versions
This project does not currently maintain multiple long-term support branches. Security fixes are expected to land on the latest mainline release/source tree.
If you are running an older version, please reproduce the issue against the latest code before reporting when possible.
### Reporting a Vulnerability
Please do not publicly disclose exploitable details before maintainers have had a reasonable chance to investigate.
Preferred report contents:
- affected version or commit;
- deployment mode and relevant configuration;
- clear reproduction steps;
- impact assessment;
- affected component, such as auth, MCP, tool execution, WebShell, C2, knowledge base, frontend, or API;
- whether the issue requires authentication;
- suggested mitigation, if known.
If the project repository has private vulnerability reporting enabled, use that channel. Otherwise, open a minimal public issue that states there is a security concern and avoid posting exploit details, credentials, target data, or weaponized payloads.
### Scope
In scope:
- authentication and session handling issues;
- authorization bypass in protected APIs;
- unsafe command execution behavior;
- unintended file read/write through tools or Skills;
- external MCP trust-boundary flaws;
- WebShell or C2 management vulnerabilities;
- sensitive data leakage from logs, audit records, uploads, or APIs;
- cross-site scripting or frontend injection in the Web UI;
- security-impacting configuration handling bugs.
Out of scope:
- reports against systems you do not own or are not authorized to test;
- denial-of-service testing against public services without permission;
- social engineering, phishing, or credential theft;
- issues caused only by intentionally disabling documented security controls;
- vulnerabilities in third-party tools invoked by CyberStrikeAI, unless CyberStrikeAI makes them materially worse.
### Authorized Use Boundary
CyberStrikeAI must only be used for education, research, and authorized security testing. Do not use it against systems without explicit permission.
High-risk capabilities such as Shell execution, WebShell management, C2, payload generation, external MCP tools, and batch scanning should be enabled only in controlled, authorized environments.
### Deployment Hardening
Before production use:
- change the default password;
- use HTTPS or a trusted reverse proxy;
- restrict access by IP, VPN, or bastion;
- enable audit logging;
- keep C2 disabled unless explicitly needed;
- review external MCP servers before enabling them;
- keep high-risk tools out of global HITL allowlists;
- back up `config.yaml`, `data/`, and custom resource directories.
See:
- [Security Model](docs/en-US/security-model.md)
- [Security Hardening](docs/en-US/security-hardening.md)
- [Runbooks](docs/en-US/runbooks.md)
---
# 安全政策
CyberStrikeAI 是一个安全测试与自动化平台。它可以执行工具、调用 MCP 服务、管理 WebShell 连接,并可选运行 C2 工作流。请把每个部署实例都视为高权限安全系统。
## 支持版本
本项目目前不维护多个长期支持分支。安全修复通常会合入最新主线版本或源码树。
如果你运行的是旧版本,建议在报告前尽量用最新代码复现问题。
## 漏洞报告
在维护者有合理时间调查前,请不要公开披露可利用细节。
建议报告内容:
- 受影响版本或 commit
- 部署方式和相关配置;
- 清晰复现步骤;
- 影响评估;
- 受影响组件,例如认证、MCP、工具执行、WebShell、C2、知识库、前端或 API
- 是否需要登录认证;
- 已知缓解建议。
如果仓库启用了私有漏洞报告,请优先使用该渠道。否则可以提交一个最小公开 Issue,说明存在安全问题,但不要发布利用细节、凭证、目标数据或武器化载荷。
## 范围
范围内:
- 认证和会话处理问题;
- 受保护 API 的授权绕过;
- 不安全的命令执行行为;
- 通过工具或 Skills 意外读写文件;
- 外部 MCP 信任边界问题;
- WebShell 或 C2 管理漏洞;
- 日志、审计、上传文件或 API 泄露敏感数据;
- Web UI 的 XSS 或前端注入;
- 影响安全的配置处理缺陷。
范围外:
- 针对未授权系统的报告;
- 未经许可的拒绝服务测试;
- 社工、钓鱼或凭证窃取;
- 仅因主动关闭文档化安全控制导致的问题;
- 第三方工具自身漏洞,除非 CyberStrikeAI 明显放大了风险。
## 授权使用边界
CyberStrikeAI 仅可用于教育、研究和授权安全测试。不要在没有明确授权的系统上使用。
Shell 执行、WebShell 管理、C2、payload 生成、外部 MCP 工具、批量扫描等高风险能力,只应在受控且授权明确的环境中启用。
## 部署加固
生产使用前:
- 修改默认密码;
- 使用 HTTPS 或可信反向代理;
- 通过 IP、VPN 或堡垒机限制访问;
- 开启审计日志;
- 不需要 C2 时保持关闭;
- 启用外部 MCP 前进行审查;
- 高风险工具不要加入全局 HITL 白名单;
- 备份 `config.yaml``data/` 和自定义资源目录。
参见:
- [安全模型](docs/zh-CN/security-model.md)
- [安全加固指南](docs/zh-CN/security-hardening.md)
- [运维 Runbooks](docs/zh-CN/runbooks.md)
+7 -3
View File
@@ -108,6 +108,12 @@ agent:
hitl:
# 全局默认审批方:human=人工审批,audit_agent=审计 Agent;未选会话时切换会写入本项,重启后仍生效
default_reviewer: human
# 审计 Agent 专用模型;字段留空则复用上方 openai 配置。建议 model 填小模型,用于降低审批成本。
audit_model:
provider: "" # openai / claude;留空跟随 openai.provider
base_url: "" # 留空跟随 openai.base_url
api_key: "" # 留空跟随 openai.api_key
model: "" # 留空跟随 openai.model,例如可填 gpt-4o-mini / qwen-turbo / deepseek-chat
# 已决策审计日志保留天数(与 MCP 监控一致;省略默认 90;0 表示不自动清理)
retention_days: 90
# 按你环境里的真实工具名增删(与侧栏一致、小写不敏感);不需要全局免审批可改为 []
@@ -396,7 +402,6 @@ agents_dir: agents
# 系统会从该目录加载所有 .yaml 格式的角色配置文件
# 每个角色应创建独立的配置文件,例如:roles/CTF.yaml, roles/默认.yaml 等
roles_dir: roles # 角色配置文件目录(相对于配置文件所在目录)
# ============================================
# 项目管理与事实黑板
# ============================================
@@ -405,7 +410,6 @@ project:
# default_project_id: "" # 可选:机器人/批量任务创建对话时的默认项目 ID
fact_index_max_runes: 65000
# 事实关系速览段预算(从索引总预算中预留)
fact_index_path_max_runes: 10000
fact_index_path_max_runes: 10000
fact_summary_max_runes: 24000
default_inject_deprecated: false
+66
View File
@@ -0,0 +1,66 @@
# CyberStrikeAI Documentation
Documentation is split by language:
- [中文文档](zh-CN/)
- [English docs](en-US/)
## 中文文档
- [部署指南](zh-CN/deployment.md)
- [运维 Runbooks](zh-CN/runbooks.md)
- [配置画像](zh-CN/configuration-profiles.md)
- [安全加固指南](zh-CN/security-hardening.md)
- [API Recipes](zh-CN/api-recipes.md)
- [贡献规范](zh-CN/contributing-guide.md)
- [配置参考](zh-CN/configuration.md)
- [安全模型](zh-CN/security-model.md)
- [架构说明](zh-CN/architecture.md)
- [API 参考](zh-CN/api-reference.md)
- [排错指南](zh-CN/troubleshooting.md)
- [审计与监控](zh-CN/audit-and-monitoring.md)
- [知识库](zh-CN/knowledge-base.md)
- [C2 使用说明](zh-CN/c2.md)
- [WebShell 管理](zh-CN/webshell.md)
- [MCP 联邦](zh-CN/mcp-federation.md)
- [Agent 与角色](zh-CN/agent-and-role-guide.md)
- [Skills 指南](zh-CN/skills-guide.md)
- [插件开发](zh-CN/plugin-development.md)
- [发布流程](zh-CN/release-process.md)
- [测试指南](zh-CN/testing.md)
- [图编排使用说明](zh-CN/workflow-graph.md)
- [人机协同最佳实践](zh-CN/hitl-best-practices.md)
- [机器人使用说明](zh-CN/robot.md)
- [视觉分析](zh-CN/VISION.md)
- [前端国际化方案](zh-CN/frontend-i18n.md)
- [Eino 多代理改造说明](zh-CN/MULTI_AGENT_EINO.md)
## English Docs
- [Deployment Guide](en-US/deployment.md)
- [Runbooks](en-US/runbooks.md)
- [Configuration Profiles](en-US/configuration-profiles.md)
- [Security Hardening](en-US/security-hardening.md)
- [API Recipes](en-US/api-recipes.md)
- [Contributing Guide](en-US/contributing-guide.md)
- [Configuration Reference](en-US/configuration.md)
- [Security Model](en-US/security-model.md)
- [Architecture](en-US/architecture.md)
- [API Reference](en-US/api-reference.md)
- [Troubleshooting](en-US/troubleshooting.md)
- [Audit and Monitoring](en-US/audit-and-monitoring.md)
- [Knowledge Base](en-US/knowledge-base.md)
- [C2 Guide](en-US/c2.md)
- [WebShell Management](en-US/webshell.md)
- [MCP Federation](en-US/mcp-federation.md)
- [Agent and Role Guide](en-US/agent-and-role-guide.md)
- [Skills Guide](en-US/skills-guide.md)
- [Plugin Development](en-US/plugin-development.md)
- [Release Process](en-US/release-process.md)
- [Testing Guide](en-US/testing.md)
- [Graph Orchestration Guide](en-US/workflow-graph.md)
- [HITL Best Practices](en-US/hitl-best-practices.md)
- [Robot / Chatbot Guide](en-US/robot.md)
- [Vision Analysis](en-US/VISION.md)
- [Frontend i18n](en-US/frontend-i18n.md)
- [Eino Multi-Agent Notes](en-US/MULTI_AGENT_EINO.md)
+66
View File
@@ -0,0 +1,66 @@
# Eino Multi-Agent Notes
[中文](../zh-CN/MULTI_AGENT_EINO.md)
CyberStrikeAI uses CloudWeGo Eino ADK for the current single-agent and multi-agent execution paths. The native legacy ReAct path has been removed.
## Entrypoints
- Single-agent: `/api/eino-agent` and `/api/eino-agent/stream`
- Multi-agent: `/api/multi-agent` and `/api/multi-agent/stream`
Multi-agent orchestration is selected by request body:
- `deep`
- `plan_execute`
- `supervisor`
Robots default to `robot_default_agent_mode`, and batch tasks can opt into multi-agent through config.
## Agent Definitions
Markdown agents live under `agents/`.
Typical files:
```text
agents/orchestrator.md
agents/orchestrator-plan-execute.md
agents/orchestrator-supervisor.md
agents/*.md
```
Front matter controls name, id, description, tools, bound role, max iterations, and optional orchestrator kind.
## Middleware
Important Eino middleware:
- tool search: exposes a small visible tool set and unlocks others on demand;
- patch tool calls: repairs interrupted histories;
- plan task: structured task board;
- reduction: truncates or persists large tool outputs;
- summarization: compresses long contexts;
- checkpoint: resume after crash/OOM.
These settings live under `multi_agent.eino_middleware`.
## Skills
Eino Skills support progressive disclosure. The Agent initially sees names and descriptions; details are loaded only when needed through the configured skill tool.
## Operational Notes
- Tool visibility is not the same as tool availability in the UI.
- Running streams keep their startup context even if config changes mid-run.
- Summarization can write transcripts under `data/conversation_artifacts/...`.
- High-risk tools should still be constrained by roles and HITL.
## Source Anchors
- Multi-agent handler: `internal/handler/multi_agent.go`
- Preparation: `internal/handler/multi_agent_prepare.go`
- Orchestration: `internal/multiagent/eino_orchestration.go`
- Run loop: `internal/multiagent/eino_adk_run_loop.go`
- Skills: `internal/multiagent/eino_skills.go`
- Middleware: `internal/multiagent/eino_middleware.go`
+29
View File
@@ -0,0 +1,29 @@
# English Docs
- [Deployment Guide](deployment.md): deployment modes, HTTPS, reverse proxy, systemd, backup, upgrade, and acceptance checks.
- [Runbooks](runbooks.md): operational steps for production setup, external MCP, KB, Web testing, C2 cleanup, and tool debugging.
- [Configuration Profiles](configuration-profiles.md): recommended profiles for dev, internal team, knowledge-only, production, C2, and MCP automation.
- [Security Hardening](security-hardening.md): pre-launch baseline, reverse proxy, HITL allowlist, file permissions, and periodic review.
- [API Recipes](api-recipes.md): examples for login, Agent, streaming, multi-agent, uploads, vulnerabilities, KB, MCP, and audit export.
- [Contributing Guide](contributing-guide.md): checklists for APIs, config, tools, frontend, DB, high-risk features, and docs.
- [Configuration Reference](configuration.md): `config.yaml` fields, hot-apply boundaries, recommended values, and source anchors.
- [Security Model](security-model.md): trust boundaries, HITL, tool execution, C2/WebShell, and data safety.
- [Architecture](architecture.md): request flow, module relationships, complexity hotspots, and design trade-offs.
- [API Reference](api-reference.md): authentication, OpenAPI, SSE, stability tiers, and common endpoints.
- [Troubleshooting](troubleshooting.md): diagnostic order, minimal commands, common misdiagnoses, and issue template.
- [Audit and Monitoring](audit-and-monitoring.md): platform audit, tool monitoring, HITL logs, and retention.
- [Knowledge Base](knowledge-base.md): indexing pipeline, retrieval tuning, log analysis, and content writing.
- [C2 Guide](c2.md): lifecycle, task classification, event review, and safety guidance.
- [WebShell Management](webshell.md): operation tiers, naming, AI guardrails, and troubleshooting.
- [MCP Federation](mcp-federation.md): built-in MCP, external MCP, lifecycle, and tool naming.
- [Agent and Role Guide](agent-and-role-guide.md): roles, sub-agents, Skills, orchestration modes, and tool visibility.
- [Skills Guide](skills-guide.md): Skill structure, progressive disclosure, anti-patterns, and local-tool risk.
- [Plugin Development](plugin-development.md): API plugins, MCP plugins, resource-pack plugins, and security boundaries.
- [Release Process](release-process.md): release risk, config compatibility, DB migrations, and acceptance checks.
- [Testing Guide](testing.md): test layers, regression focus, test data, and failure cases.
- [Graph Orchestration Guide](workflow-graph.md)
- [HITL Best Practices](hitl-best-practices.md)
- [Robot / Chatbot Guide](robot.md)
- [Vision Analysis](VISION.md)
- [Frontend i18n](frontend-i18n.md)
- [Eino Multi-Agent Notes](MULTI_AGENT_EINO.md)
+61
View File
@@ -0,0 +1,61 @@
# Vision Analysis
[中文](../zh-CN/VISION.md)
Vision analysis registers the `analyze_image` MCP tool when enabled. It is intended for screenshots, captchas, UI states, and image evidence in authorized workflows.
## Config
```yaml
vision:
enabled: true
model: qwen-vl
api_key: ""
base_url: ""
provider: ""
max_image_bytes: 5242880
max_dimension: 2048
jpeg_quality: 82
max_payload_bytes: 524288
detail: auto
timeout_seconds: 60
```
Empty `api_key`, `base_url`, or `provider` inherits from `openai`.
## Data Handling
Image bytes are sent only to the vision model call. Agent history keeps text summaries, not raw image bytes. This reduces context size and accidental image propagation.
## Preprocessing
The runtime can resize and recompress large images based on:
- maximum file size;
- maximum dimension;
- JPEG quality;
- encoded payload size.
If small images are already under limits, preprocessing may be skipped.
## Usage Guidance
Use vision for:
- UI screenshots;
- visual vulnerability evidence;
- captcha or image-based prompts in authorized tests;
- interpreting tool screenshots.
Do not use it for:
- unrelated personal images;
- sensitive screenshots without authorization;
- long-term storage of raw evidence when a text summary is enough.
## Source Anchors
- Tool registration: `internal/app/vision_tools.go`
- Client: `internal/vision/client.go`
- Preprocess: `internal/vision/preprocess.go`
- Config: `internal/config/vision.go`
+79
View File
@@ -0,0 +1,79 @@
# Agent and Role Guide
[中文](../zh-CN/agent-and-role-guide.md)
Agent behavior is shaped by roles, Markdown sub-agents, Skills, tool visibility, and HITL policy.
## Responsibility Boundaries
| Resource | Purpose | Not for |
| --- | --- | --- |
| Role | identity, tone, tool boundary, authorization rules | large reference material |
| Agent Markdown | multi-agent specialization, handoff format, local strategy | one-off facts |
| Skill | reusable procedures, checklists, templates, references | permission control |
Authorization boundaries belong in roles and HITL first, not only in Skills.
## Modes
| Mode | Good for | Poor fit |
| --- | --- | --- |
| `eino_single` | short tasks, interactive analysis | large multi-stage work |
| `deep` | dynamic task decomposition | strict sequential workflows |
| `plan_execute` | plan, execute, replan loops | frequent user interruption |
| `supervisor` | expert routing | vague or too many sub-agents |
Start with `eino_single`; use `plan_execute` for structured projects; use `deep` or `supervisor` when specialist agents matter.
## Markdown Sub-Agent
Example:
```yaml
---
name: Vulnerability Triage
id: vulnerability-triage
description: Validate, classify, and summarize vulnerability evidence
tools:
- nmap
- nuclei
bind_role: 综合漏洞扫描
max_iterations: 200
---
```
The body should define scope, tool order, output format, and prohibited actions.
## Tool Visibility
With `tool_search`, the model initially sees only a subset of tools:
- visible in UI does not mean visible in current model context;
- `tool_search_always_visible_tools` are easier to call;
- clear tool descriptions improve search hits;
- sub-agent tool constraints still matter.
When a tool is not used, check role tools, sub-agent tools, tool_search config, and description.
## Output Format
Sub-agents should return structured results:
```markdown
## Conclusion
## Evidence
- Tool:
- Key output:
- Confidence:
## Risks
## Suggested next step
```
This helps the orchestrator continue and supports reporting.
## Source Anchors
- Markdown Agent parser: `internal/agents/markdown.go`
- Multi-agent preparation: `internal/handler/multi_agent_prepare.go`
- Orchestration: `internal/multiagent/eino_orchestration.go`
- Tool search middleware: `internal/multiagent/eino_middleware.go`
+153
View File
@@ -0,0 +1,153 @@
# API Recipes
[中文](../zh-CN/api-recipes.md)
Common API workflows for scripts and plugins. Use `/api-docs` and `/api/openapi/spec` for complete schemas.
## Recipe 1: Login and Validate
```bash
curl -k https://127.0.0.1:8080/api/auth/login \
-H "Content-Type: application/json" \
-d '{"password":"<password>"}'
```
Use:
```text
Authorization: Bearer <token>
```
Validate:
```bash
curl -k https://127.0.0.1:8080/api/auth/validate \
-H "Authorization: Bearer <token>"
```
## Recipe 2: Create Conversation and Send Message
Simplest path: call Agent without pre-creating an empty conversation.
```bash
curl -k https://127.0.0.1:8080/api/eino-agent \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"message":"Run authorized basic read-only recon against 127.0.0.1"}'
```
If you need an empty conversation first:
```bash
curl -k https://127.0.0.1:8080/api/conversations \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"title":"Web Test"}'
```
Then pass `conversationId` to the Agent request.
## Recipe 3: Stream Agent Output
```bash
curl -k -N https://127.0.0.1:8080/api/eino-agent/stream \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"message":"Summarize current project facts and propose read-only next steps"}'
```
Notes:
- `-N` disables curl buffering.
- reverse proxy buffering must also be disabled.
- wait for `done`.
## Recipe 4: Multi-Agent
```bash
curl -k -N https://127.0.0.1:8080/api/multi-agent/stream \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"message":"Run a staged authorized Web security test; plan first, execute read-only steps",
"orchestration":"plan_execute"
}'
```
Options:
- `deep`
- `plan_execute`
- `supervisor`
## Recipe 5: Upload Attachment
```bash
curl -k https://127.0.0.1:8080/api/chat-uploads \
-H "Authorization: Bearer <token>" \
-F "file=@./request.txt"
```
Upload large files and reference them in messages instead of pasting raw content.
## Recipe 6: Create Vulnerability
```bash
curl -k https://127.0.0.1:8080/api/vulnerabilities \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"title":"Example SQL Injection",
"severity":"high",
"target":"https://example.com/item?id=1",
"description":"Parameter id has verified SQL injection",
"evidence":"read-only validation output...",
"remediation":"Use parameterized queries"
}'
```
Check OpenAPI for exact fields.
## Recipe 7: Search Knowledge Base
```bash
curl -k https://127.0.0.1:8080/api/knowledge/search \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"query":"How to infer SQL injection column count",
"riskType":"SQL Injection",
"topK":5,
"threshold":0.4
}'
```
If empty, check categories first.
## Recipe 8: External MCP Status
```bash
curl -k https://127.0.0.1:8080/api/external-mcp/stats \
-H "Authorization: Bearer <token>"
```
If service is running but Agent cannot find tools, check role constraints and `tool_search`.
## Recipe 9: Tool Schema
```bash
curl -k https://127.0.0.1:8080/api/config/tools/nmap/schema \
-H "Authorization: Bearer <token>"
```
Scripts should build args from schema rather than guessing field names.
## Recipe 10: Export Audit Logs
```bash
curl -k "https://127.0.0.1:8080/api/audit/logs/export" \
-H "Authorization: Bearer <token>" \
-o audit.csv
```
Exported logs may contain sensitive operational data. Store encrypted.
+103
View File
@@ -0,0 +1,103 @@
# API Reference
[中文](../zh-CN/api-reference.md)
CyberStrikeAI exposes built-in OpenAPI docs:
```text
/api-docs
GET /api/openapi/spec
```
The OpenAPI spec is protected to avoid exposing the API surface to unauthenticated users.
## Authentication
Login:
```http
POST /api/auth/login
Content-Type: application/json
{"password":"your-password"}
```
The auth middleware accepts token from:
1. `Authorization: Bearer <token>`
2. `Authorization: <token>`
3. `?token=<token>`
4. `auth_token` cookie
Prefer `Authorization: Bearer` for scripts. Query tokens can leak through logs.
## Agent APIs
Single-agent:
- `POST /api/eino-agent`
- `POST /api/eino-agent/stream`
Multi-agent:
- `POST /api/multi-agent`
- `POST /api/multi-agent/stream`
`orchestration` may be `deep`, `plan_execute`, or `supervisor`.
## SSE Notes
Streaming endpoints are long-lived. Clients should:
- handle `error` events;
- wait for `done`;
- avoid blindly replaying destructive requests;
- disable proxy buffering;
- pass `conversationId` when continuing a conversation.
## Stability Tiers
| API type | Stability | Recommendation |
| --- | --- | --- |
| `/api/auth/*` | high | safe to integrate |
| `/api/eino-agent*` | high | preferred chat entry |
| `/api/openapi/spec` | high | client generation |
| `/api/config*` | medium | admin automation only |
| `/api/c2/*`, `/api/webshell/*` | medium | high-risk, restrict access |
| frontend private calls | low | avoid plugin dependency |
## Common Areas
- Conversations: `/api/conversations`
- Projects/facts: `/api/projects`
- Vulnerabilities: `/api/vulnerabilities`
- Knowledge: `/api/knowledge/*`
- Roles: `/api/roles`
- Skills: `/api/skills`
- External MCP: `/api/external-mcp`
- Monitoring: `/api/monitor`
- Audit: `/api/audit`
- C2: `/api/c2`
- WebShell: `/api/webshell`
## Curl Example
```bash
curl -k https://127.0.0.1:8080/api/conversations \
-H "Authorization: Bearer <token>"
```
```bash
curl -k https://127.0.0.1:8080/api/eino-agent \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"message":"Run authorized basic recon against 127.0.0.1; avoid high-risk actions."}'
```
## Source Anchors
- Routes: `internal/app/app.go`
- Auth middleware: `internal/security/auth_middleware.go`
- OpenAPI: `internal/handler/openapi.go`
- Single-agent: `internal/handler/eino_single_agent.go`
- Multi-agent: `internal/handler/multi_agent.go`
+74
View File
@@ -0,0 +1,74 @@
# Architecture
[中文](../zh-CN/architecture.md)
CyberStrikeAI is a single Go Web application with a static frontend, SQLite persistence, Agent orchestration, MCP tooling, workflow graphs, knowledge retrieval, and optional C2/WebShell subsystems.
## Overview
```mermaid
flowchart LR
U["Web / Robot / API"] --> R["Gin Router"]
R --> H["Handlers"]
H --> DB["SQLite"]
H --> A["Agent / Multi-Agent"]
A --> M["MCP Server"]
M --> T["Built-in / YAML / Skill tools"]
M --> EM["External MCP"]
A --> K["Knowledge Retrieval"]
H --> W["Workflow Runtime"]
H --> C2["C2"]
H --> WS["WebShell"]
H --> AU["Audit / Monitor"]
```
## Request Path
For `/api/eino-agent/stream`:
1. Gin route enters auth middleware.
2. Handler parses message, conversation, role, uploads, and WebShell context.
3. Agent builds model input: history, role prompt, project facts, tools.
4. Eino Runner calls the model.
5. Tool requests go through MCP.
6. HITL may interrupt before execution.
7. Tool results are saved to process details and monitoring.
8. Model continues and produces final text.
9. SSE streams progress and deltas to the browser.
10. Conversation and process details persist to SQLite.
This explains why a failure may live in auth, config, model, MCP, HITL, DB, SSE, or frontend rendering.
## Cross-Cutting Modules
- Project facts are injected into Agent context.
- HITL sits before tool execution.
- Monitor records tool execution and supports cancellation/review.
- Audit records platform management actions.
- Tool search controls what tools the model can currently see.
These are not just pages; they affect many runtime paths.
## Complexity Hotspots
- `internal/app/app.go`: service construction and route wiring.
- `internal/handler/config.go`: hot application of config across model, KB, C2, robot, MCP.
- `internal/multiagent/`: streaming, retry, summarization, middleware, tools.
- `internal/security/`: auth and shell execution boundary.
- `internal/database/`: SQLite schema compatibility.
## Design Trade-Offs
The project uses a single Go service, static frontend, and SQLite to keep deployment simple. The trade-offs:
- multi-instance scale is not automatic;
- runtime files must be backed up carefully;
- high-privilege tools and admin UI live in one process, so deployment isolation matters.
## Source Anchors
- App wiring: `internal/app/app.go`
- Handlers: `internal/handler/`
- Multi-agent: `internal/multiagent/`
- MCP: `internal/mcp/`
- DB: `internal/database/`
+87
View File
@@ -0,0 +1,87 @@
# Audit and Monitoring
[中文](../zh-CN/audit-and-monitoring.md)
CyberStrikeAI has separate observability streams:
- Audit: who performed platform management actions.
- Monitor: how tool executions ran.
- HITL logs: why a tool call was approved, edited, or rejected.
- Process details: how an Agent chained reasoning, tools, and outputs.
Use them together during review.
## Audit
Config:
```yaml
audit:
enabled: true
retention_days: 15
max_detail_bytes: 8192
```
Endpoints:
- `GET /api/audit/meta`
- `GET /api/audit/summary`
- `GET /api/audit/logs`
- `GET /api/audit/logs/:id`
- `GET /api/audit/logs/export`
Watch for login failures, password changes, config updates, external MCP changes, WebShell/C2 actions, and HITL rejections.
## Tool Monitoring
Config:
```yaml
monitor:
retention_days: 90
```
Endpoints:
- `GET /api/monitor`
- `GET /api/monitor/execution/:id`
- `POST /api/monitor/execution/:id/cancel`
- `GET /api/monitor/stats`
- `GET /api/monitor/calls-timeline`
Monitoring is for execution state, duration, cancellation, and result review. It is not a substitute for platform audit.
## Retention Guidance
Security-tool logs can include targets, paths, commands, and sensitive outputs. Longer retention is not always safer.
- Short engagements: 15-30 days.
- Continuous red-team platform: 90-180 days.
- Compliance archive: export and encrypt.
## Review Checklist
Weekly:
- failed logins and unusual IPs;
- config changes;
- long-running or frequently failing tools;
- external MCP state;
- DB size and disk.
After engagement:
- export required evidence;
- delete stale WebShell/C2 resources;
- clean uploads and temporary workspaces;
- archive reports, vulnerabilities, and project facts.
## Source Anchors
- Audit service: `internal/audit/service.go`
- Sanitization: `internal/audit/sanitize.go`
- Retention: `internal/audit/retention.go`
- Audit handler: `internal/handler/audit.go`
- Monitor: `internal/monitor/reconcile.go`
- Monitor handler: `internal/handler/monitor.go`
- HITL logs: `internal/handler/hitl_logs.go`
+68
View File
@@ -0,0 +1,68 @@
# C2 Guide
[中文](../zh-CN/c2.md)
The built-in C2 subsystem is for authorized environments only. Disable it when not needed:
```yaml
c2:
enabled: false
```
## Objects
- Listener: receives sessions.
- Session: connected implant/session.
- Task: command or operation assigned to a session.
- Payload: generated binary or one-liner.
- Profile: communication configuration.
- Event: runtime event stream.
- File: upload/download channel.
APIs live under `/api/c2`; disabled C2 returns `503 c2_disabled`.
## Lifecycle
Correct C2 operation is a lifecycle:
1. Authorization: project, targets, time window, allowed actions.
2. Profile design: transport, sleep, callback address.
3. Listener start: port, network path, logs.
4. Payload generation: hash, purpose, delivery method.
5. Session intake: confirm host identity and privilege.
6. Tasking: only authorized tasks.
7. Result archival: project facts or report.
8. Cleanup: stop listeners, delete payloads, clear stale sessions/events.
Skipping authorization and profile design makes the rest hard to audit.
## Task Classification
| Level | Example | Approval |
| --- | --- | --- |
| L1 read-only identity | `whoami`, hostname | audit agent may approve |
| L2 environment enum | interfaces, processes | strict review |
| L3 file access | read config, download result | human confirms path |
| L4 change execution | upload, run script, sleep change | human approval |
| L5 persistence/lateral/destructive | startup, creds, delete, spread | reject unless explicit authorization |
Put this classification into HITL prompts for practical decisions.
## Review Questions
- Which listener received which session?
- Who generated the payload and when?
- Which authorized target does the session represent?
- Which tasks were issued?
- Were outputs saved into facts or reports?
- Were listener and payload cleaned up?
## Source Anchors
- Manager: `internal/c2/manager.go`
- Listener: `internal/c2/listener.go`
- HTTP listener: `internal/c2/listener_http.go`
- TCP listener: `internal/c2/listener_tcp.go`
- Payload: `internal/c2/payload_builder.go`
- Handler: `internal/handler/c2.go`
- MCP tools: `internal/app/c2_tools.go`
+159
View File
@@ -0,0 +1,159 @@
# Configuration Profiles
[中文](../zh-CN/configuration-profiles.md)
These profiles are not full `config.yaml` files. They show the key sections that most affect safety and operability.
## Local Development
Goal: easy debugging with local capabilities.
Common startup:
```bash
chmod +x run.sh && ./run.sh
```
```yaml
server:
host: 127.0.0.1
port: 8080
tls_enabled: true
tls_auto_self_sign: true
auth:
password: "dev-only-change-me"
audit:
enabled: true
retention_days: 7
c2:
enabled: false
multi_agent:
enabled: true
eino_skills:
filesystem_tools: true
```
Not for shared or public use.
## Internal Team
Goal: shared team instance with audit and limited high-risk surface.
```yaml
server:
host: 127.0.0.1
port: 8080
tls_enabled: false
auth:
password: "<long-random-password>"
audit:
enabled: true
retention_days: 30
monitor:
retention_days: 90
c2:
enabled: false
mcp:
enabled: false
hitl:
default_reviewer: human
tool_whitelist: [read_file, glob, grep, tool_search]
```
Pair with reverse-proxy HTTPS, IP allowlist, and backups.
## Knowledge-Only Assistant
Goal: use CyberStrikeAI as a knowledge-augmented assistant with minimal attack surface.
```yaml
c2:
enabled: false
mcp:
enabled: false
knowledge:
enabled: true
base_path: knowledge_base
retrieval:
top_k: 5
similarity_threshold: 0.4
multi_agent:
eino_skills:
filesystem_tools: false
```
Use read-only roles and avoid storing sensitive customer data.
## High-Audit Production
Goal: long-running production red-team or security platform.
```yaml
auth:
password: "<managed-secret>"
session_duration_hours: 8
audit:
enabled: true
retention_days: 90
monitor:
retention_days: 180
hitl:
default_reviewer: human
retention_days: 180
tool_whitelist: [read_file, glob, grep, tool_search]
c2:
enabled: false
multi_agent:
eino_callbacks:
enabled: true
mode: log_only
sse_trace_to_client: false
```
Pair with proxy auth, dedicated OS user, log collection, encrypted backups, and project closeout cleanup.
## C2 Exercise Window
Goal: temporarily enable C2 only during authorized exercise.
```yaml
c2:
enabled: true
hitl:
default_reviewer: human
tool_whitelist: [read_file, glob, grep, tool_search]
audit:
enabled: true
monitor:
retention_days: 180
```
Requirements:
- confirm scope before exercise;
- separate listener ports from admin UI;
- run C2 cleanup afterward;
- restore `c2.enabled: false`.
## External MCP Automation
Goal: connect trusted internal tool services.
```yaml
external_mcp:
servers: {}
multi_agent:
eino_middleware:
tool_search_enable: true
tool_search_min_tools: 20
hitl:
default_reviewer: audit_agent
tool_whitelist: [read_file, glob, grep, tool_search]
```
Guidance:
- every MCP tool needs clear schema;
- high-risk MCP tools stay out of allowlist;
- stdio MCP gets its own working directory;
- HTTP MCP must authenticate.
+86
View File
@@ -0,0 +1,86 @@
# Configuration Reference
[中文](../zh-CN/configuration.md)
The main configuration file is `config.yaml`. Many fields are editable through the Web settings page, but not every field has the same hot-apply behavior.
## Core Sections
```yaml
server:
host: 0.0.0.0
port: 8080
tls_enabled: true
auth:
password: "change-me"
session_duration_hours: 12
openai:
provider: openai
base_url: https://api.openai.com/v1
api_key: sk-...
model: gpt-4.1
agent:
max_iterations: 12000
tool_timeout_minutes: 60
```
Change the default password immediately. Use HTTPS or a trusted reverse proxy in any shared environment.
## Hot-Apply Boundaries
`POST /api/config/apply` coordinates model config, tool description mode, MCP tool registration, knowledge components, robot restarts, and C2 runtime reconciliation. It does not make every field instantly effective.
| Section | Usually hot-applies | Extra action |
| --- | --- | --- |
| `openai` | new requests use new model settings | running streams keep their current state |
| `agent.max_iterations` | new tasks | existing tasks continue |
| `hitl.tool_whitelist` | new approval checks | pending approvals are not re-decided |
| `knowledge.enabled` | initializes/updates components | scan and index are still required |
| `knowledge.embedding` | updates retriever/indexer config | rebuild index for existing vectors |
| `robots` | restarts long-lived connections | platform callback settings must still match |
| `c2.enabled` | reconciles C2 runtime | verify existing listeners/sessions manually |
| `server.port/tls` | usually needs process restart | listener settings are not ordinary hot state |
## Fallback Relationships
- `vision.api_key/base_url/provider` can inherit from `openai`.
- `hitl.audit_model` can inherit from `openai`.
- `knowledge.embedding.base_url/api_key` can inherit from model settings.
- rerank config can inherit from embedding/openai.
- `database.knowledge_db_path` can be separate or reuse the main DB.
When debugging, inspect both the child config and the fallback parent.
## Recommended Values
| Field | Conservative | Aggressive | Decide by |
| --- | --- | --- | --- |
| `agent.tool_timeout_minutes` | 10-30 | 60+ | long scanners |
| `shell_no_output_timeout_seconds` | 300-600 | 1200+ | quiet tools |
| `knowledge.indexing.batch_size` | 5-10 | 20+ | embedding API limits |
| `knowledge.indexing.rate_limit_delay_ms` | 300-800 | 0-100 | 429 frequency |
| `retrieval.top_k` | 3-5 | 8-12 | context budget |
| `similarity_threshold` | 0.35-0.45 | 0.5+ | recall vs precision |
| `audit.retention_days` | 15-30 | 90+ | compliance and disk |
## Change Template
Before changing config, write down:
```text
Purpose:
Sections:
Expected impact:
Rollback:
Validation endpoints:
```
After changing, validate the specific subsystem rather than trusting the save message.
## Source Anchors
- Config structs: `internal/config/config.go`
- Env expansion: `internal/config/envexpand.go`
- Config API and apply: `internal/handler/config.go`
- Route registration: `internal/app/app.go`
- C2 reconciliation: `internal/app/c2_lifecycle.go`
+115
View File
@@ -0,0 +1,115 @@
# Contributing Guide
[中文](../zh-CN/contributing-guide.md)
This guide defines baseline expectations when adding features, APIs, tools, frontend pages, or docs.
## Principles
- New features need documentation.
- New APIs need OpenAPI updates.
- New frontend text needs zh-CN and en-US i18n.
- New config must state hot-apply behavior.
- New high-risk tools must define HITL policy.
- New DB fields must be compatible with old databases.
- New long-running tasks need state, cancellation, or recovery strategy.
## New API Checklist
- Handler validates parameters.
- Error response has stable `error` and readable `message`.
- Endpoint is authenticated unless it is an explicit platform callback.
- Mutations write audit events.
- Long tasks write monitoring/task state.
- `internal/handler/openapi.go` updated.
- API docs or recipes updated.
- Handler tests added.
## New Config Checklist
- Field exists in `config.Config`.
- `config.yaml` sample has comments.
- Safe default when omitted.
- Old configs still start.
- Hot-apply behavior documented.
- Web settings do not delete unknown fields.
- Security docs updated if high-risk capability is affected.
## New Tool Checklist
For YAML tools and Go MCP tools:
- stable and specific tool name;
- searchable `short_description`;
- explicit input schema, not one raw `cmd`;
- readable and stable output;
- controlled timeout and error path;
- high-risk operation not globally allowlisted;
- docs explain use case and risk.
## New Frontend Page Checklist
- Reuse `apiFetch`, modal, notifications, and existing state patterns.
- Add all visible text to `zh-CN.json` and `en-US.json`.
- Include loading, empty, and error states.
- Confirm destructive/high-risk actions.
- Avoid overflow in long English labels.
- Browser console clean.
## DB Change Checklist
- Migration is idempotent.
- Old DB upgrades.
- Defaults are safe.
- Large indexes are deliberate.
- Empty DB and old DB tested.
- Release notes mention backup.
## High-Risk Capability Checklist
High-risk includes Shell, WebShell, C2, external MCP write/execute, credential access, and bulk scanning.
Answer:
- Who can call it?
- Does it require HITL?
- What is audited?
- How can it be cancelled?
- How is cleanup done?
- How can it be disabled?
- Is it off by default?
## Documentation Requirements
Each important feature should document:
- purpose;
- config;
- workflow;
- risk boundary;
- troubleshooting;
- source anchors.
Chinese and English docs must have matching filenames:
```text
docs/zh-CN/
docs/en-US/
```
Update:
- `docs/README.md`
- `docs/zh-CN/README.md`
- `docs/en-US/README.md`
## Review Focus
Prioritize:
- behavior regressions;
- security boundaries;
- old data compatibility;
- error handling;
- test gaps;
- docs and OpenAPI sync.
+113
View File
@@ -0,0 +1,113 @@
# Deployment Guide
[中文](../zh-CN/deployment.md)
CyberStrikeAI can run as a local testing tool, an internal team service, or a production red-team platform. Treat it as a high-privilege security system: it can execute commands, call MCP tools, manage WebShell connections, and optionally run C2 listeners.
## Prerequisites
- Go for source runs and binary builds.
- Python for some MCP servers and tool scripts.
- SQLite files under `data/`; no external DB is required by default.
- Actual security tools installed in PATH. YAML files under `tools/` only describe commands.
- An OpenAI-compatible model endpoint, or `openai.provider: claude` for the Claude bridge.
Important persistent paths:
```text
config.yaml
data/
tools/
roles/
skills/
agents/
knowledge_base/
chat_uploads/
```
Back these up before upgrades.
## Startup Modes
Local quick start:
```bash
chmod +x run.sh && ./run.sh
```
`run.sh` is the most common startup path for local use, development, small temporary internal deployments, and quick post-upgrade verification.
For long-running service, boot-time startup, managed logs, and crash recovery, prefer a binary managed by systemd.
Source run:
```bash
go run ./cmd/server --config config.yaml
```
Binary build:
```bash
go build -o cyberstrike-ai ./cmd/server
./cyberstrike-ai --config config.yaml
```
The binary still needs `web/templates`, `web/static`, and the runtime resource directories.
## HTTPS and Reverse Proxy
For local testing, self-signed HTTPS is acceptable:
```yaml
server:
tls_enabled: true
tls_auto_self_sign: true
```
For production, use real certificates or terminate TLS at a reverse proxy. If the proxy terminates TLS and forwards HTTP to the app, avoid enabling app-side TLS on the same upstream unless `proxy_pass` uses HTTPS.
Nginx must not buffer SSE:
```nginx
proxy_buffering off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
```
## Deployment Decision Table
| Scenario | Recommended setup | Key settings | Avoid |
| --- | --- | --- | --- |
| Personal testing | `./run.sh` + self-signed HTTPS | `tls_auto_self_sign: true` | Public exposure |
| Internal team | Binary + systemd + internal HTTPS | strong password, audit, backup, IP restrictions | Shared weak password |
| Production red-team platform | Reverse proxy + dedicated OS user + log collection | real certs, proxy auth, C2 only when needed | Direct public admin UI |
| Chat/KB only | Disable C2 and unnecessary MCP | `c2.enabled: false` | All tools enabled by default |
| Tool automation | Isolated workspace + HITL | `workspace_root_dir`, `hitl`, `monitor` | Shell tools globally allowlisted |
## Acceptance Checklist
After startup:
1. Open `/` and verify no HTTP/HTTPS redirect loop.
2. Login and validate `/api/auth/validate`.
3. Run model test in settings.
4. Check tool list and schemas.
5. If KB is enabled, check index status.
6. If external MCP is enabled, verify connection and tool visibility.
7. If C2 is enabled, start and stop a test listener only in an authorized network.
8. Check audit logs for login and config activity.
## Runtime File Layers
- Replaceable: binary, `web/`, default docs/resources.
- Preserve: `config.yaml`, `data/`, custom tools/roles/skills/agents, `knowledge_base`, uploads.
- Cleanup candidates: checkpoints, temporary workspaces, stale payloads, old tool execution records.
## Source Anchors
- App wiring and routes: `internal/app/app.go`
- TLS bootstrap: `internal/app/main_server_tls.go`
- HTTP to HTTPS redirect: `internal/app/main_server_http_redirect.go`
- Config structs: `internal/config/config.go`
- Config apply: `internal/handler/config.go`
+111
View File
@@ -0,0 +1,111 @@
# Developer Guide
[中文](../zh-CN/developer-guide.md)
This guide is for contributors extending CyberStrikeAI. The project is a Go single-service application with a static frontend, SQLite persistence, Agent/MCP orchestration, and optional high-risk security subsystems.
## Project Layout
```text
cmd/server/ service entrypoint
internal/app/ app wiring, routes, MCP tool registration
internal/handler/ HTTP handlers
internal/database/ SQLite access
internal/security/ auth, rate limits, shell execution
internal/mcp/ MCP server and external MCP manager
internal/multiagent/ Eino single-agent, multi-agent, middleware
internal/workflow/ graph orchestration runtime
internal/knowledge/ indexing and retrieval
internal/c2/ built-in C2
internal/project/ project fact blackboard
web/static/ frontend JS/CSS/assets
web/templates/ HTML templates
tools/ YAML command tools
roles/ role YAML
agents/ multi-agent Markdown definitions
skills/ Agent Skills
docs/ documentation
```
## Development Startup
```bash
go run ./cmd/server --config config.yaml
```
The frontend is static. Most JS/CSS/template changes only require a browser refresh.
## Adding a Business Module
Do not add only a handler. A complete module usually needs:
1. Data model and SQLite migration.
2. Handler: parameters, errors, pagination/filtering.
3. Audit: management actions.
4. Monitor: long-running execution state.
5. MCP: whether Agents should call it.
6. HITL: approval boundary for MCP tools.
7. OpenAPI: update `/api/openapi/spec`.
8. Frontend: i18n, states, empty/error UI.
9. Tests: DB, handler, edge cases.
10. Docs: config, usage, troubleshooting, safety impact.
Missing one of these usually becomes a later usability or safety bug.
## Error Response Design
Prefer stable JSON:
```json
{
"error": "machine_readable_code",
"message": "human-readable explanation"
}
```
Frontend needs stable fields, users need actionable messages, and logs need detailed internal errors.
## Long-Running Tasks
For scanning, indexing, batch tasks, C2, or external operations, answer:
- Can it be cancelled?
- Can progress be queried?
- Can it be retried?
- Where is the result stored?
- Does state survive page refresh?
- Does it block the HTTP request?
If not, use task tables, event streams, or monitoring.
## Extending Tools
Prefer `tools/*.yaml` for command tools. Use Go built-in tools when the tool needs internal state or structured integration.
Built-in tools should define clear input schemas, handle timeouts and errors, and respect HITL for risky actions.
## Frontend Changes
Use existing helpers such as `apiFetch`, modal utilities, notifications, and i18n. Update both `web/static/i18n/zh-CN.json` and `web/static/i18n/en-US.json` for new visible text.
Avoid putting secrets or provider keys in frontend code.
## Test Priority
High-value tests:
- config hot-apply;
- HITL branches;
- shell timeout/no-output;
- external MCP recovery;
- KB indexing and post-processing;
- WebShell OS/encoding detection;
- SQLite migration compatibility.
## Source Anchors
- App wiring: `internal/app/app.go`
- Config apply: `internal/handler/config.go`
- OpenAPI: `internal/handler/openapi.go`
- Tool executor: `internal/security/executor.go`
- Skill package: `internal/skillpackage/`
+54
View File
@@ -0,0 +1,54 @@
# Frontend i18n
[中文](../zh-CN/frontend-i18n.md)
CyberStrikeAI frontend i18n is static and lightweight. Text is organized in JSON files and applied through `data-i18n` attributes plus JavaScript helper functions.
## Files
```text
web/static/i18n/zh-CN.json
web/static/i18n/en-US.json
web/static/js/i18n.js
```
## Key Principles
- Keep keys stable and semantic.
- Update Chinese and English together.
- Do not hardcode new visible text in JS when it should be localized.
- Preserve default HTML text as fallback before JS initialization.
## HTML Usage
```html
<button data-i18n="common.save">保存</button>
```
For attributes, follow the existing `i18n.js` conventions.
## JavaScript Usage
Use the global translation helper where available:
```javascript
const label = t('common.save');
```
When adding dynamic UI, make sure language switching refreshes the text or re-renders the component.
## Migration Workflow
1. Add or update UI text.
2. Add keys to `zh-CN.json`.
3. Add matching keys to `en-US.json`.
4. Replace hardcoded text with `data-i18n` or `t()`.
5. Test both languages and browser console.
## Common Pitfalls
- Missing keys only in one language.
- Dynamic text built from hardcoded fragments.
- Button labels too long in English.
- HTML fallback text diverges from JSON text.
- Adding new page text without updating language switch behavior.
+122
View File
@@ -0,0 +1,122 @@
# Human-in-the-loop (HITL) Best Practices
[中文](../zh-CN/hitl-best-practices.md)
HITL reviews tool calls before an Agent executes them. Use it to control high-risk operations, keep an audit trail, and let an Audit Agent take over routine approvals when human reviewers cannot keep up.
## Where To Configure
Open **System Settings → Human-in-the-loop** in the web UI. You can configure:
- Global default reviewer: `human` or `audit_agent`
- Dedicated Audit Agent model: `hitl.audit_model`
- Resolved audit log retention days
- No-approval tool allowlist: `hitl.tool_whitelist`
- Audit prompts for approval mode and review-edit mode
Example `config.yaml`:
```yaml
hitl:
default_reviewer: human
audit_model:
provider: ""
base_url: ""
api_key: ""
model: "" # set a small model here; blank reuses openai.model
retention_days: 90
tool_whitelist: [read_file, list_dir, glob, grep, tool_search]
```
`audit_model` supports partial configuration. Empty fields inherit from the main `openai` config, so the common setup is to fill only `model` and run approvals on a cheaper small model.
## Recommended Approval Strategy
### 1. Start With Humans, Then Delegate Gradually
At the beginning, prefer:
- `default_reviewer: human`
- Only clearly read-only tools in `tool_whitelist`
- Human approval for file writes, command execution, C2 tasks, and WebShell operations
After observing audit logs, move repeated low-risk operations into the allowlist.
### 2. Use A Small Model When Humans Cannot Keep Up
When pending approvals start piling up, switch routine review to the Audit Agent:
```yaml
hitl:
default_reviewer: audit_agent
audit_model:
model: "your-small-reviewer-model"
```
Good candidates for small-model review:
- Read-only queries
- Reconnaissance
- Port and service scans
- Directory enumeration
- Non-destructive validation commands
Keep human review for:
- Deleting, overwriting, or clearing data
- Modifying permissions, passwords, or accounts
- Persistence, lateral movement, and high-risk C2 tasks
- Writes against production targets
### 3. Encode Your Policy In The Prompt
The Audit Agent prompt should describe an operational policy, not just say “be careful.” Make it explicit:
- Which low-risk actions are normally approved
- Which destructive actions must be rejected
- Which cases require escalation to a human
- How review-edit mode may narrow arguments
Example policy snippet:
```text
Approve routine reconnaissance, read-only queries, and port scans by default.
Reject file deletion, database clearing, account or permission changes, persistence, and stopping critical services.
Reject actions outside the user-authorized target scope.
In review-edit mode, you may narrow paths, targets, or command arguments before approving, but must not expand the attack surface.
```
### 4. Keep The Allowlist Conservative
Allowlisted tools skip approval, so keep the list stable and low-risk. Recommended examples:
- `read_file`
- `list_dir`
- `glob`
- `grep`
- `tool_search`
Avoid globally allowlisting:
- Arbitrary shell execution tools
- File write/delete tools
- C2 task tools
- WebShell command execution tools
## Mode Selection
| Mode | Best for |
|------|----------|
| Off | Local labs or fully trusted toolchains |
| Approval | Approve/reject only |
| Review-edit | Let the Audit Agent narrow arguments before approval |
If you configured a small audit model, start with **Approval** mode. Use **Review-edit** only when you want the AI to safely narrow paths, target ranges, or command arguments.
## Operations Tips
- Review **Human-in-the-loop → Audit logs** regularly and tune allowlists/prompts.
- In high-risk environments, keep `default_reviewer: human` and use the Audit Agent only for recommendations.
- If the small-model reviewer fails, CyberStrikeAI rejects conservatively by default.
- After changing `hitl.audit_model`, click **Test audit model** in the settings page.
- For production, customer, or real business systems, keep a human as the final approver.
+107
View File
@@ -0,0 +1,107 @@
# Knowledge Base
[中文](../zh-CN/knowledge-base.md)
The knowledge base turns local security notes, playbooks, vulnerability guides, and organizational standards into retrievable context for Agents.
## Enable
```yaml
knowledge:
enabled: true
base_path: knowledge_base
embedding:
provider: openai
model: text-embedding-v4
database:
knowledge_db_path: data/knowledge.db
```
Keep the knowledge DB separate when you want portable reusable indexes.
## Internal Pipeline
```mermaid
flowchart LR
F["Markdown / Web item"] --> M["Manager"]
M --> C["Chunker"]
C --> E["Embedding"]
E --> V["SQLite Vector Index"]
Q["Agent query"] --> MQ["MultiQuery"]
MQ --> V
V --> R["Rerank"]
R --> P["Post-process"]
P --> A["Agent context"]
```
Quality depends on source structure, chunk size, embedding quality, and rerank behavior.
## Content Writing
Bad:
```text
SQL injection is dangerous. Use sqlmap. Filter input.
```
Better:
```markdown
# MySQL UNION Injection Verification
## Preconditions
- Parameter is concatenated into SELECT.
## Steps
1. Use `order by` to infer column count.
2. Use `union select null,...` to find reflection.
3. Use read-only functions to confirm DB type.
## False Positives
- WAF error page.
- Generic error page.
## Fix
- Parameterized queries.
- Least DB privilege.
```
Structured headings and concrete steps improve chunking and retrieval.
## Tuning
Use a fixed test query set, then change one variable at a time:
- empty results: lower `similarity_threshold`, verify indexing;
- wrong topic: improve titles and category/risk type;
- broken context: tune `chunk_size` and `chunk_overlap`;
- noisy results: raise threshold or fix rerank;
- high cost: lower `multi_query.max_queries`, `prefetch_top_k`, or `top_k`.
## MCP Tools
Enabled KB registers tools such as:
- list risk types;
- search knowledge base.
Prompt roles to query the KB before giving vulnerability validation or remediation advice when unsure.
## Retrieval Logs
Use logs to improve content:
- frequent no-results queries: missing content or synonyms;
- low scores: titles/terms mismatch;
- duplicate hits: merge or categorize docs;
- Agent ignores results: output may be too long or not actionable.
## Source Anchors
- Manager: `internal/knowledge/manager.go`
- Index pipeline: `internal/knowledge/index_pipeline.go`
- Chunking: `internal/knowledge/chunk_eino.go`
- Retriever: `internal/knowledge/retriever.go`
- Eino chain: `internal/knowledge/eino_retrieve_chain.go`
- Rerank: `internal/knowledge/rerank_http.go`
- MCP tools: `internal/knowledge/tool.go`
+86
View File
@@ -0,0 +1,86 @@
# MCP Federation
[中文](../zh-CN/mcp-federation.md)
CyberStrikeAI uses MCP as the primary tool protocol. Tools can be built-in, YAML-backed, Skill-local, or provided by external MCP servers.
## Built-In MCP
The internal MCP server registers:
- YAML command tools;
- security execution tools;
- knowledge tools;
- project fact tools;
- C2 tools;
- WebShell tools;
- batch task tools;
- vision analysis.
Agents usually call these internally without extra setup.
## HTTP MCP
```yaml
mcp:
enabled: true
host: 0.0.0.0
port: 8081
auth_header: "X-MCP-Token"
auth_header_value: "random-secret"
```
Always set an auth value and restrict network access.
## External MCP Lifecycle
1. Register config: name, type, command/URL, environment.
2. Start connection: stdio process or HTTP/SSE client.
3. Pull tool list: names, descriptions, schemas.
4. Expose to Agent: affected by role, tool_search, HITL.
5. Execute: validate args, call, monitor.
6. Recover: handle process/network failure.
7. Stop/delete: remove runtime and config.
Debug by locating the failed step.
## Tool Naming
Good names are stable, specific, and action-object oriented:
```text
burp_send_to_repeater
asset_lookup_domain
cloud_list_public_buckets
```
Avoid:
```text
run
execute
scan
tool1
```
Specific names improve tool_search and reduce misuse.
## Security Review
Before connecting an external MCP, ask:
- Can it read/write local files?
- Can it execute commands?
- What network does it access?
- Does it send data to third parties?
- Are tool descriptions trustworthy?
- Can output contain prompt injection?
- Should it run under a separate OS user or container?
## Source Anchors
- External manager: `internal/mcp/external_manager.go`
- Recovery: `internal/mcp/connection_recovery.go`
- Tool adapter: `internal/einomcp/mcp_tools.go`
- Handler: `internal/handler/external_mcp.go`
- Invoke notification: `internal/einomcp/tool_invoke_notify.go`
+120
View File
@@ -0,0 +1,120 @@
# Plugin Development
[中文](../zh-CN/plugin-development.md)
Plugins live under `plugins/`. The repo ships two reference implementations: **Burp Suite extension** and **Chromium DevTools extension**. Integrations typically use HTTP APIs, MCP servers, or resource packs (tools, roles, Skills, agents).
## Layout
```text
plugins/
README.md
burp-suite/cyberstrikeai-burp-extension/
browser-extension/cyberstrikeai-browser-extension/
```
## Plugin Layers
| Layer | Example | Benefit | Cost |
| --- | --- | --- | --- |
| API plugin | Burp / browser extension calling Agent Stream | simple UI integration | depends on API/auth |
| MCP plugin | exposes tools to Agent | Agent can call it | needs schema and safety design |
| Resource pack | ships tools/roles/skills/agents | simple and versionable | less interactive |
Do not start with MCP unless the Agent must actively call your capability. For “send this HTTP request to AI”, an API plugin is enough.
## Burp Suite Extension
Java extension under `plugins/burp-suite/cyberstrikeai-burp-extension/`. Typical flow: read HTTP from Burp → format prompt → call CyberStrikeAI SSE → show Progress/Final in a Burp tab.
Build: JDK + Gradle/Maven → `bash build-mvn.sh``dist/cyberstrikeai-burp-extension.jar`.
## Browser Extension (Chromium DevTools)
MV3 DevTools extension under `plugins/browser-extension/cyberstrikeai-browser-extension/`. Aligned with the Burp plugin: capture Network traffic → HTTP/1.1 prompt → SSE output. Full docs: `README.md` / `README.zh-CN.md` in that directory.
Load unpacked at `chrome://extensions/`, or `bash package.sh``dist/cyberstrikeai-browser-extension.zip`.
### Auth best practices (browser)
Server `POST /api/auth/login` returns `{ token, expires_at }`. There is **no refresh token** — do not assume silent renewal. Reference: `lib/auth-session.js`, `lib/api.js`, `panel/panel.js`.
| Practice | Description |
| --- | --- |
| Session storage | Store token + `expires_at` in `chrome.storage.session`; never persist password |
| Remaining time | Show `OK · 11h 30m left`; warn when <30min |
| Local check | Re-check `expires_at` + `GET /api/auth/validate` every 30s |
| Server probe | Immediate probe when DevTools panel becomes visible |
| Unreachable | Show warning; keep token during transient outage |
| 401/403 | Clear token (server restart clears in-memory sessions) |
| Before Send | `ensureAuthReady()` before SSE |
| Permissions | `optional_host_permissions` — request origin on Validate |
After extension reload, close DevTools completely and reopen F12 (stale panel context).
### Data and performance (browser)
- Caps: 200 captures/tab, 20 tabs, 512KB progress/run.
- Default XHR/Fetch only; use pause toggle when not capturing.
- Truncate or summarize large bodies before sending to Agent.
## API Integration
- Login: `POST /api/auth/login`, then `GET /api/auth/validate`.
- Persist `expires_at`; re-login when expired (no silent refresh).
- Prefer `/api/eino-agent/stream` or `/api/multi-agent/stream` (SSE).
- Large files: `/api/chat-uploads`, then reference in message.
- Full spec: `/api-docs` or `/api/openapi/spec`.
## API Plugin Payload
Include:
- source tool and context;
- target URL, method, key headers;
- truncation policy for request/response bodies;
- user intent;
- authorization boundary.
Large responses should be uploaded or summarized, not pasted whole into the prompt.
## MCP Schema Design
Bad:
```json
{"cmd":{"type":"string"}}
```
Better:
```json
{
"target_url": {"type":"string","description":"authorized target URL"},
"scan_profile": {"type":"string","enum":["passive","active-safe"]},
"max_requests": {"type":"integer","description":"request limit"}
}
```
Specific schemas make HITL and Agent behavior safer.
## Security Boundaries
Plugins should not bypass platform controls:
- no hidden destructive local commands;
- no plaintext long-lived credentials (password only for login; token in session storage);
- no default third-party data exfiltration;
- no dependency on browser state to bypass login;
- on 401/403, clear session and require re-auth — do not silently retry.
## Source Anchors
- Burp plugin: `plugins/burp-suite/cyberstrikeai-burp-extension/src/main/java/burp/`
- Browser extension: `plugins/browser-extension/cyberstrikeai-browser-extension/`
- Auth: `lib/auth-session.js`, `lib/api.js`, `lib/storage.js`
- UI: `panel/panel.js`
- Capture: `devtools.js`, `background/service-worker.js`
- OpenAPI: `internal/handler/openapi.go`
- External MCP: `internal/handler/external_mcp.go`
- Web auth reference: `web/static/js/auth.js`
+67
View File
@@ -0,0 +1,67 @@
# Release Process
[中文](../zh-CN/release-process.md)
Use this guide for maintainers and operators preparing upgrades or releases.
## Pre-Release Checklist
- README and docs updated.
- `config.yaml` sample includes new fields.
- OpenAPI includes new endpoints.
- i18n updated when frontend text changed.
- Security docs updated for high-risk capabilities.
## Release Risk Tiers
| Change | Risk | Must test |
| --- | --- | --- |
| Docs/assets | low | links/rendering |
| Frontend | medium | login, page states, API errors |
| Handler/API | medium | OpenAPI, auth, errors |
| Config struct | high | old config compatibility, ApplyConfig |
| DB schema | high | old DB migration, rollback |
| Agent/MCP/HITL | high | tools, approvals, streaming |
| C2/WebShell/Terminal | critical | authorized lab, audit, disable switch |
Release notes should call out risk, not just features.
## Config Compatibility
New fields should:
- have safe defaults;
- allow old configs to start;
- be documented in sample `config.yaml`;
- not cause Web settings to delete unknown fields;
- be tested via restart and hot-apply paths.
Avoid default-enabling high-risk capabilities.
## Database Changes
SQLite migrations must be:
- compatible with old versions;
- idempotent after interruption;
- careful with nullable/default fields;
- mindful of large indexes and locks;
- documented with backup instructions.
## Build and Test
```bash
go test ./internal/...
go test ./cmd/...
go build -o cyberstrike-ai ./cmd/server
```
Manual smoke:
```text
login -> model test -> new chat -> tools -> HITL -> KB -> external MCP -> C2 enable/disable
```
## Rollback
Restore binary/code, `config.yaml`, and `data/` together. If a new version changed DB schema, replacing only the binary is not a reliable rollback.
+1 -1
View File
@@ -1,6 +1,6 @@
# CyberStrikeAI Robot / Chatbot Guide
[中文](robot.md)
[中文](../zh-CN/robot.md)
This document explains how to chat with CyberStrikeAI from **personal WeChat**, **DingTalk**, **Lark (Feishu)**, and **WeCom (Enterprise WeChat)** using long-lived connections or HTTP callbacks—no need to open a browser on the server. Following the steps below helps avoid common mistakes.
+188
View File
@@ -0,0 +1,188 @@
# Runbooks
[中文](../zh-CN/runbooks.md)
Runbooks are task-oriented procedures you can follow during real operations.
## Runbook 1: Production Instance from Zero to Ready
Use for first-time internal or production red-team deployment.
For local or temporary verification, start with the bundled script:
```bash
chmod +x run.sh && ./run.sh
```
After it is verified, decide whether to move to systemd plus reverse proxy for long-running deployment.
### Preconditions
- Host is managed as an asset.
- Access path is decided: internal network, VPN, bastion, or reverse proxy.
- Model API key and model are available.
- C2, WebShell, and external MCP policy is decided.
### Steps
1. Prepare directory:
```bash
mkdir -p /opt/CyberStrikeAI
```
2. Place binary and resources:
```text
cyberstrike-ai
web/
tools/
roles/
skills/
agents/
docs/
config.yaml
```
3. Set baseline config:
```yaml
auth:
password: "<long-random-password>"
server:
host: 127.0.0.1
port: 8080
tls_enabled: false
audit:
enabled: true
c2:
enabled: false
```
4. Configure HTTPS at the reverse proxy and restrict source IPs.
5. Run with systemd.
6. Login and test the model.
7. Check tools and audit logs.
8. Create backup policy.
### Acceptance
- `/api/auth/validate` succeeds after login.
- Model test passes.
- Tools load.
- Audit shows login.
- C2 is disabled when not needed.
## Runbook 2: Connect External MCP
### Preconditions
- MCP service is trusted.
- You know whether it can read/write files, execute commands, or access networks.
- Transport is chosen: stdio, HTTP, or SSE.
### Steps
1. Add service in External MCP page.
2. For stdio, configure command, args, cwd, and env.
3. For HTTP/SSE, configure URL and auth.
4. Start service.
5. Check `/api/external-mcp/stats`.
6. Confirm tools and schemas.
7. Execute one low-risk tool call.
8. Keep high-risk tools out of global allowlist.
### Acceptance
- MCP status is running.
- Tool schemas are visible.
- Agent can find tools through `tool_search`.
- Monitor records tool execution.
- Audit records config change.
## Runbook 3: Enable and Tune Knowledge Base
### Steps
1. Enable config:
```yaml
knowledge:
enabled: true
base_path: knowledge_base
retrieval:
top_k: 5
similarity_threshold: 0.4
```
2. Put Markdown files under `knowledge_base/`.
3. Scan directory.
4. Rebuild index.
5. Prepare 5-10 fixed test queries.
6. Search and record hits.
7. Tune threshold, top_k, chunking, and document titles.
### Acceptance
- Index status is complete.
- Common queries hit correct docs.
- Agent consults KB when uncertain.
- Retrieval logs show query and hit docs.
## Runbook 4: Authorized Web Test Workflow
1. Create project and record scope.
2. Start conversation and bind project.
3. Choose minimal role.
4. State target, time window, and prohibited actions.
5. Start with read-only recon.
6. Record useful leads as project facts.
7. Use HITL for risky validation.
8. Save confirmed issues to vulnerability management.
9. Generate attack-chain/report material.
10. Clean uploads, workspace, and unnecessary execution logs.
Acceptance:
- Each vulnerability has evidence, impact, reproduction, and fix.
- Risky actions have HITL records.
- Project facts reconstruct the path.
- Report excludes unrelated sensitive data.
## Runbook 5: C2 Cleanup After Exercise
1. Stop all listeners.
2. List sessions and confirm no authorized session remains active.
3. Export required task results.
4. Delete or archive payloads.
5. Delete stale tasks, events, and files.
6. Review C2 audit trail.
7. Write key results to project facts or report.
8. Set `c2.enabled: false` unless continuously needed.
Acceptance:
- No running listener.
- No pending task.
- Payloads are not publicly downloadable.
- Audit/report explains the lifecycle.
## Runbook 6: Agent Does Not Call a Tool
Check in order:
1. Role includes the tool.
2. Tool appears in `/api/config/tools`.
3. `tool_search` is not hiding it.
4. Tool name and description are clear.
5. HITL is not pending.
6. Agent is not in final summarization phase.
7. Sub-agent does not have a narrower tool list.
Fix:
- add tool to role;
- improve `short_description`;
- add to `tool_search_always_visible_tools`;
- prompt when to use it;
- inspect process details and monitor records.
+130
View File
@@ -0,0 +1,130 @@
# Security Hardening
[中文](../zh-CN/security-hardening.md)
This checklist covers pre-production and continuous hardening for CyberStrikeAI.
## Before Going Live
- Change `auth.password` to a long random secret.
- Use HTTPS or a trusted reverse proxy.
- Restrict access by IP, VPN, or bastion.
- Enable `audit.enabled`.
- Set `c2.enabled: false` when C2 is not required.
- Do not expose standalone HTTP MCP without strong auth and network isolation.
- Connect only trusted external MCP services.
- Back up `config.yaml`, `data/`, and custom resource directories.
## Reverse Proxy Baseline
```nginx
client_max_body_size 200m;
proxy_buffering off;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
```
Recommended security headers:
```nginx
add_header X-Content-Type-Options nosniff;
add_header Referrer-Policy no-referrer;
add_header X-Frame-Options DENY;
```
## HITL Allowlist Baseline
Minimal allowlist:
```yaml
hitl:
tool_whitelist:
- read_file
- glob
- grep
- tool_search
```
Do not globally allowlist:
- `execute`;
- WebShell write/execute tools;
- C2 task/payload tools;
- high-risk external MCP tools;
- delete, write, upload, persistence tools.
## File Permissions
```bash
chmod 600 config.yaml
chmod 700 data
```
Run under a dedicated OS user. Avoid root unless explicitly required.
## External MCP Review
Before connecting:
- Can it execute commands?
- Can it read/write local files?
- Does it send data to third parties?
- Does it authenticate?
- Can output contain untrusted model/web content?
- Should it run in a container or separate user?
After connecting:
- keep high-risk tools out of allowlist;
- review tool list changes;
- audit config changes.
## C2 and WebShell
C2:
- disabled by default;
- enabled only during authorized window;
- listener ports separated from admin UI;
- cleanup payloads, sessions, tasks, and events.
WebShell:
- authorized targets only;
- clear naming;
- write/delete/execute requires approval;
- delete connections after project end.
## Retention
Suggested:
- audit: 30-90 days;
- monitor: 90-180 days;
- uploads: clean after project;
- C2/WebShell outputs: keep only report evidence;
- knowledge base: no real credentials or customer secrets.
## Periodic Review
Weekly:
- failed logins and unusual IPs;
- config changes;
- external MCP changes;
- long-running tools;
- unexpected C2 enablement;
- stale WebShell connections;
- disk and DB size.
Project closeout:
- clean temp workspaces;
- delete unnecessary uploads;
- archive evidence;
- delete stale WebShell/C2 resources;
- export audit records.
+72
View File
@@ -0,0 +1,72 @@
# Security Model
[中文](../zh-CN/security-model.md)
CyberStrikeAI is not a generic chatbot. It is a high-privilege security automation system with command execution, MCP tools, WebShell management, optional C2, batch tasks, and multi-agent orchestration.
## Trust Boundaries
Main actors:
- Web user: can chat, change settings, manage resources, and trigger tools.
- Agent: selects tools based on role, context, and middleware.
- MCP tools: may access files, run commands, call services, or touch targets.
- External MCP: third-party local or remote tool providers.
- Robot callbacks: platform-authenticated message ingress outside Web login.
Anyone who can log into the Web UI should be treated as an operator of the instance.
## Threat Model
| Threat | Path | Impact | Controls |
| --- | --- | --- | --- |
| Password leak | login, then use terminal/WebShell/C2 | platform takeover | strong password, HTTPS, internal network, audit |
| Prompt injection | target content instructs Agent to misuse tools | unauthorized actions | role boundaries, HITL, least tools |
| Malicious MCP | external tool lies or has side effects | host/target impact | trusted MCP only, isolation |
| Tool YAML tampering | command template changed | malicious execution | file permissions, review |
| C2 misuse | payload or task against unauthorized target | legal and business risk | disabled by default, approvals |
| WebShell misuse | destructive command on business host | outage/data loss | naming, read-only first, HITL |
| DB leak | copy `data/*.db` or uploads | sensitive target data | permissions, encrypted backups |
## HITL Is Not Magic
HITL sees a tool name, arguments, and context. It does not always see real-world impact. Be conservative when:
- a harmless-looking command wraps `bash -c` or base64;
- the MCP tool description is untrusted;
- WebShell target identity is vague;
- C2 payload delivery happens outside the platform;
- a read-only tool can still create traffic or side effects.
Audit Agent is useful for routine checks, not for replacing humans on destructive operations.
## Data Minimization
Avoid long-term storage of:
- real customer credentials;
- raw production data;
- long-lived cookies;
- unrelated scan output;
- stale WebShell or C2 sessions.
Project closeout should include cleanup of uploads, WebShell connections, C2 payloads, temporary workspaces, and bulky execution logs.
## Production Baseline
- Strong password and HTTPS.
- Internal/VPN/proxy restricted access.
- `audit.enabled: true`.
- Random `mcp.auth_header_value` when HTTP MCP is exposed.
- `c2.enabled: false` unless required.
- Minimal external MCP.
- No high-risk tools in global allowlist.
## Source Anchors
- Sessions: `internal/security/auth_manager.go`
- Auth middleware: `internal/security/auth_middleware.go`
- Rate limiting: `internal/security/ratelimit.go`
- Shell execution: `internal/security/executor.go`
- HITL execution: `internal/handler/hitl_execution.go`
- Audit service: `internal/audit/service.go`
+70
View File
@@ -0,0 +1,70 @@
# Skills Guide
[中文](../zh-CN/skills-guide.md)
Skills provide reusable procedures, checklists, templates, and references that Agents can load when needed. A Skill should be an executable procedure, not an encyclopedia page.
## Structure
```text
skills/
ssrf-testing/
SKILL.md
REFERENCE.md
```
`SKILL.md` front matter:
```markdown
---
name: ssrf-testing
description: SSRF identification, validation, bypass, and remediation workflow
---
```
The description determines when the Agent loads it.
## Recommended Sections
```markdown
## When to use
## Preconditions
## Procedure
## Stop conditions
## Output
```
Stop conditions matter: they tell the Agent when to escalate, ask for approval, or stop expanding scope.
## Anti-Patterns
| Anti-pattern | Result | Fix |
| --- | --- | --- |
| Description too broad | triggers too often | make it scenario-specific |
| Encyclopedia content | Agent lacks next step | write procedures and decisions |
| Secrets in Skill | leakage/misuse | use runtime config or user input |
| One huge Skill | costly and noisy | split by task/vulnerability |
| No stop condition | scope creep | define approval/stop rules |
## Skill vs Knowledge Base
- Skill: how to do something.
- Knowledge base: facts, references, cases.
For SSRF, a Skill describes the test procedure; the KB stores metadata addresses, bypass cases, and remediation references.
## Local Tool Risk
`filesystem_tools: true` exposes local read/write/execute capability. In production:
- constrain workspace;
- require HITL for write/execute;
- do not globally allowlist `execute`;
- make Skills explicitly avoid out-of-scope files.
## Source Anchors
- Validation: `internal/skillpackage/validate.go`
- Service: `internal/skillpackage/service.go`
- Eino Skills: `internal/multiagent/eino_skills.go`
- Handler: `internal/handler/skills.go`
+78
View File
@@ -0,0 +1,78 @@
# Testing Guide
[中文](../zh-CN/testing.md)
Testing CyberStrikeAI means more than running Go tests. Agent, MCP, HITL, C2, WebShell, and frontend streaming all have different failure modes.
## Commands
```bash
go test ./internal/...
go test ./cmd/...
go build -o cyberstrike-ai ./cmd/server
```
Run focused packages when working locally:
```bash
go test ./internal/multiagent
go test ./internal/handler
go test ./internal/security
```
## Test Pyramid
| Layer | Goal | Example |
| --- | --- | --- |
| Unit | pure logic | expressions, chunking, sanitization |
| Handler | HTTP behavior | validation, auth, status codes |
| Integration | module cooperation | external MCP, KB indexing, HITL |
| Smoke | user path | login, chat, tools, settings |
| Authorized lab | high-risk features | C2, WebShell, terminal |
Do not use end-to-end manual testing as a substitute for unit tests, or unit tests as a substitute for high-risk lab validation.
## Regression Focus
Expand testing when changing:
- `internal/handler/config.go`: model, KB, MCP, C2, robot apply paths;
- `internal/multiagent/`: streaming, tool calls, summarization, retry, HITL;
- `internal/security/`: auth, shell, timeout, no-output;
- `internal/database/`: old data compatibility;
- `web/static/js/chat.js`: chat, process details, attack chain, groups.
## Test Data
Avoid real customer data. Prepare:
- small Markdown KB sample;
- fake local MCP server;
- controlled local HTTP target;
- harmless WebShell simulator;
- temporary SQLite DB.
## Failure Cases
Cover:
- model API 401/429/500;
- MCP startup failure;
- tool timeout;
- HITL rejection;
- interrupted KB indexing;
- unwritable database;
- WebShell non-200 response;
- C2 disabled endpoint access.
## Source Anchors
Existing tests live across:
- `internal/handler/*_test.go`
- `internal/multiagent/*_test.go`
- `internal/workflow/*_test.go`
- `internal/knowledge/*_test.go`
- `internal/security/*_test.go`
- `internal/mcp/*_test.go`
- `internal/c2/*_test.go`
+98
View File
@@ -0,0 +1,98 @@
# Troubleshooting
[中文](../zh-CN/troubleshooting.md)
Debug by layer. Do not change random config before locating the failing layer.
## Diagnostic Order
1. Process: is the service alive, any panic?
2. Network: port, HTTPS, reverse proxy, browser console.
3. Auth: does `/api/auth/validate` return 200?
4. Config: can `/api/config` be read and applied?
5. Model: does model test pass?
6. Tools: do tool list and schemas look right?
7. Database: is `data/` writable, any lock?
8. Subsystem: KB, MCP, C2, WebShell minimal action.
## Minimal Commands
```bash
lsof -i :8080
curl -k -I https://127.0.0.1:8080/
curl -k -I https://127.0.0.1:8080/static/logo.png
ls -lh data/
```
If a reverse proxy is involved, test both proxy address and upstream address.
## Common Issues
Page inaccessible:
- wrong protocol, especially HTTPS vs HTTP;
- self-signed cert warning;
- port occupied;
- reverse proxy loop.
Login fails:
- wrong `auth.password`;
- config not applied/restarted;
- stale cookie;
- audit throttling repeated failures.
Model fails:
- wrong `base_url` path;
- invalid API key;
- model unavailable;
- reasoning fields unsupported by gateway. Try `openai.reasoning.mode: off`.
Streaming stalls:
- proxy buffers SSE;
- model gateway timeout;
- context too large;
- browser/network interruption.
Tool fails:
- real command not installed;
- YAML schema wrong;
- HITL rejected or pending;
- timeout or no-output timeout.
Knowledge base empty:
- `knowledge.enabled` false;
- scan/index not run;
- embedding API failed;
- threshold or risk type too strict.
C2 returns 503:
- expected when `c2.enabled: false`.
## Common Misdiagnoses
- "Model is broken": HITL is waiting.
- "Tool missing": tool_search hides it from current context.
- "Knowledge base useless": index not rebuilt or risk type too narrow.
- "Config saved but ineffective": listener/TLS changes need restart.
- "Robot silent": platform callback or signature config wrong.
## Issue Template
```text
Version:
Startup method:
Access path:
Relevant config:
Steps:
Expected:
Actual:
Server logs:
Browser console:
API response:
```
+68
View File
@@ -0,0 +1,68 @@
# WebShell Management
[中文](../zh-CN/webshell.md)
WebShell management stores authorized WebShell connections and allows command/file operations through the UI and Agent tools.
## Workflow
1. Add a connection.
2. Fill URL, parameter/password, and metadata.
3. Test connectivity.
4. Run read-only identification commands first.
5. Let AI assist only after selecting the correct connection.
Connections are stored in SQLite.
## Operation Tiers
| Tier | Operation | Risk | Guidance |
| --- | --- | --- | --- |
| Identify | `whoami`, `pwd`, OS version | low | may automate |
| Enumerate | dirs, processes, env vars | medium | constrain path/command |
| Read | config, logs, source | medium-high | human confirms sensitivity |
| Write/execute | write, run script, delete | high | human approval and rollback |
Having a WebShell does not make follow-up operations low risk.
## Naming
Use:
```text
<project>-<environment>-<target>-<privilege>-<date>
```
Example:
```text
acme-staging-web01-www-20260707
```
Avoid vague names like `test`, `shell1`, or `customer machine`.
## AI Guardrail Prompt
```text
Before using WebShell, confirm connection_id, target name, current directory, and privilege. Default to read-only commands. Any write, delete, upload, permission change, persistence, credential access, or internal probing requires purpose, impact, rollback plan, and approval.
```
## MCP Tools
Typical tools:
- `webshell_exec`
- `webshell_file_list`
- `webshell_file_read`
- `webshell_file_write`
- connection management tools
Do not put write/execute tools in a global allowlist.
## Source Anchors
- Handler: `internal/handler/webshell.go`
- Context: `internal/handler/webshell_context.go`
- Probe: `internal/handler/webshell_probe.go`
- Encoding/OS tests: `internal/handler/webshell_encoding_test.go`, `internal/handler/webshell_os_test.go`
- Tool registration: `internal/app/app.go`
@@ -1,6 +1,6 @@
# CyberStrikeAI Graph Orchestration Guide
[中文](workflow-graph.md)
[中文](../zh-CN/workflow-graph.md)
This document explains how to use **Graph Orchestration**: building workflows on the canvas, configuring node types, passing data between nodes, and binding a graph to a role for automatic execution.
+29
View File
@@ -0,0 +1,29 @@
# 中文文档
- [部署指南](deployment.md):部署形态、HTTPS、反向代理、systemd、备份、升级和验收。
- [运维 Runbooks](runbooks.md):生产部署、外部 MCP、知识库、Web 测试、C2 清理和工具排障的操作步骤。
- [配置画像](configuration-profiles.md):本地开发、内网团队、知识库、高审计生产、C2 演练等推荐配置。
- [安全加固指南](security-hardening.md):上线前基线、反向代理、HITL 白名单、文件权限和周期巡检。
- [API Recipes](api-recipes.md):登录、Agent、流式、多代理、上传、漏洞、知识库、MCP 和审计导出示例。
- [贡献规范](contributing-guide.md):新增 API、配置、工具、前端、数据库、高风险能力和文档的 checklist。
- [配置参考](configuration.md)`config.yaml` 字段、热应用边界、参数建议和源码锚点。
- [安全模型](security-model.md):信任边界、HITL、工具执行、C2/WebShell 与数据安全。
- [架构说明](architecture.md):请求路径、模块关系、复杂度热点和设计取舍。
- [API 参考](api-reference.md):认证、OpenAPI、SSE、稳定性分层和常用接口。
- [排错指南](troubleshooting.md):诊断顺序、最小命令、常见误判和故障模板。
- [审计与监控](audit-and-monitoring.md):平台审计、工具监控、HITL 日志和保留策略。
- [知识库](knowledge-base.md):索引链路、检索调参、日志分析和内容写法。
- [C2 使用说明](c2.md):生命周期、任务分级、事件复盘和安全建议。
- [WebShell 管理](webshell.md):操作分层、连接命名、AI 约束和排错。
- [MCP 联邦](mcp-federation.md):内置 MCP、外部 MCP、生命周期和工具命名。
- [Agent 与角色](agent-and-role-guide.md):角色、子代理、Skill、编排模式和工具可见性。
- [Skills 指南](skills-guide.md):Skill 结构、渐进式披露、反模式和本地工具风险。
- [插件开发](plugin-development.md):API 插件、MCP 插件、资源包插件和安全边界。
- [发布流程](release-process.md):发布风险、配置兼容、数据库迁移和验收。
- [测试指南](testing.md):测试分层、回归重点、测试数据和失败用例。
- [图编排使用说明](workflow-graph.md)
- [人机协同最佳实践](hitl-best-practices.md)
- [机器人使用说明](robot.md)
- [视觉分析](VISION.md)
- [前端国际化方案](frontend-i18n.md)
- [Eino 多代理改造说明](MULTI_AGENT_EINO.md)
+197
View File
@@ -0,0 +1,197 @@
# Agent 与角色指南
CyberStrikeAI 的 Agent 行为由三类资源共同决定:角色、子代理和 Skills。角色决定当前任务身份和可用工具;子代理决定多代理分工;Skills 提供可按需加载的专题知识与流程。
## 角色
角色文件位于 `roles/`,格式为 YAML。角色通常包含:
- 名称。
- 描述。
- 系统提示词。
- 可用工具列表。
设计原则:
- 专用角色只绑定必要工具。
- 提示词明确授权边界。
- 对高风险操作要求先说明影响并等待审批。
- 输出格式尽量稳定,便于报告和复盘。
示例方向:
- 信息收集。
- Web 应用扫描。
- API 安全测试。
- 云安全审计。
- 数字取证。
- 二进制分析。
- CTF。
## 单代理
单代理接口:
- `POST /api/eino-agent`
- `POST /api/eino-agent/stream`
适合:
- 快速问答。
- 单目标测试。
- 工具链较短的任务。
- 需要稳定上下文的交互式分析。
## 多代理模式
多代理接口:
- `POST /api/multi-agent`
- `POST /api/multi-agent/stream`
编排模式:
- `deep`:主代理拆解任务,按需调用子代理。
- `plan_execute`:先规划,再执行,必要时重规划。
- `supervisor`:主管代理根据进展转交不同子代理。
适合:
- 多阶段渗透测试。
- 大范围信息收集。
- 需要并行角色分工的分析。
- 长任务和批量任务。
## 子代理 Markdown
子代理位于 `agents/*.md`。Front matter 示例:
```yaml
---
name: Attack Surface Enumeration
id: attack-surface-enumeration
description: 枚举目标暴露面并整理可验证线索
tools:
- subfinder
- nmap
- http-framework-test
bind_role: 信息收集
max_iterations: 300
---
```
正文写系统提示词。建议包含:
- 职责边界。
- 输入期望。
- 使用工具顺序。
- 输出格式。
- 禁止事项。
## 主代理
主代理可用:
- `agents/orchestrator.md`
- `agents/orchestrator-plan-execute.md`
- `agents/orchestrator-supervisor.md`
或在 front matter 中设置 `kind: orchestrator`。每种编排只应有一个主代理定义。
## 工具选择
工具选择顺序建议:
1. 角色绑定最小工具集。
2. 子代理按任务补充专用工具。
3. `tool_search` 动态解锁大量工具。
4. 高风险工具由 HITL 审批。
不要给所有角色默认绑定全部工具,否则上下文成本和误调用风险都会上升。
## 提示词建议
好的角色提示词应说明:
- 只在授权范围内行动。
- 先确认目标和约束。
- 对写入、删除、爆破、持久化、C2、WebShell 等操作请求审批。
- 输出可复核证据。
- 不确定时标注假设,不编造结果。
## 调试
如果 Agent 选错工具:
- 缩小角色工具列表。
- 增强工具 `short_description`
- 开启或调整 `tool_search_always_visible_tools`
- 在角色提示词中明确工具使用顺序。
如果多代理跑偏:
- 检查子代理描述是否过宽。
- 降低 `sub_agent_user_context_max_runes` 或明确任务输入。
- 优化 orchestrator 提示词。
- 查看过程详情和工具执行监控。
## 角色、子代理、Skill 的职责边界
三者经常混用,建议这样分工:
| 资源 | 解决的问题 | 不适合承载 |
| --- | --- | --- |
| Role | 当前对话的身份、语气、工具边界和授权规则 | 大量参考资料 |
| Agent Markdown | 多代理中的专业分工、交接格式和局部策略 | 一次性任务事实 |
| Skill | 可复用方法论、检查清单、模板和长参考资料 | 权限控制 |
如果把授权边界写进 Skill,而角色没有限制工具,Agent 仍可能在未加载 Skill 前选错工具。权限边界应优先放在 Role 和 HITL 中。
## 编排模式选择
| 模式 | 适合 | 不适合 |
| --- | --- | --- |
| `eino_single` | 短任务、交互式分析、需要稳定上下文 | 多阶段大任务 |
| `deep` | 主代理动态拆分任务,子代理按需深入 | 需要严格步骤顺序的流程 |
| `plan_execute` | 有明确阶段、需要执行后复盘和重规划 | 用户频繁打断的即兴对话 |
| `supervisor` | 专家分工明确,需要主管路由 | 子代理定义含糊或过多 |
经验上,普通安全测试先用 `eino_single`;复杂项目用 `plan_execute`;需要多个专业角色时用 `deep``supervisor`
## 工具可见性如何影响行为
多代理里 `tool_search` 会让模型一开始只看见部分常驻工具。结果是:
- 工具页面显示可用,不代表模型当前上下文可见。
- `tool_search_always_visible_tools` 里的工具更容易被模型调用。
- 工具描述越清晰,越容易被搜索命中。
- 子代理自己的 `tools` 限制仍然很重要。
调试“Agent 为什么不用某工具”时,要同时检查角色工具、子代理工具、tool_search 配置和工具描述。
## 好的子代理输出格式
子代理不要只返回“已完成”。建议固定格式:
```markdown
## 结论
## 证据
- 命令/工具:
- 关键输出:
- 置信度:
## 风险
## 建议下一步
```
这样主代理才能继续编排,也方便攻击链和项目事实沉淀。
## 源码锚点
- Markdown Agent 解析:`internal/agents/markdown.go`
- 多代理准备:`internal/handler/multi_agent_prepare.go`
- 编排实现:`internal/multiagent/eino_orchestration.go`
- 工具搜索中间件:`internal/multiagent/eino_middleware.go`
- 子代理上下文:`internal/multiagent/sub_agent_context_test.go`
+153
View File
@@ -0,0 +1,153 @@
# API Recipes
[English](../en-US/api-recipes.md)
本文给出外部脚本或插件常用的 API 调用配方。完整字段以 `/api-docs``/api/openapi/spec` 为准。
## Recipe 1:登录并验证
```bash
curl -k https://127.0.0.1:8080/api/auth/login \
-H "Content-Type: application/json" \
-d '{"password":"<password>"}'
```
后续请求推荐使用:
```bash
Authorization: Bearer <token>
```
验证:
```bash
curl -k https://127.0.0.1:8080/api/auth/validate \
-H "Authorization: Bearer <token>"
```
## Recipe 2:创建对话并发送消息
最简单方式是不先创建空对话,直接调用 Agent:
```bash
curl -k https://127.0.0.1:8080/api/eino-agent \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"message":"对 127.0.0.1 做授权的基础信息收集,只做只读操作"}'
```
如果需要先创建对话:
```bash
curl -k https://127.0.0.1:8080/api/conversations \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"title":"Web 测试"}'
```
然后把返回的 `conversationId` 放入 Agent 请求。
## Recipe 3:流式调用 Agent
```bash
curl -k -N https://127.0.0.1:8080/api/eino-agent/stream \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"message":"总结当前项目事实并列出下一步,只读"}'
```
注意:
- `-N` 禁用 curl 缓冲。
- 反向代理也要关闭 buffering。
- 收到 `done` 才算本轮结束。
## Recipe 4:调用多代理
```bash
curl -k -N https://127.0.0.1:8080/api/multi-agent/stream \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"message":"对授权目标做分阶段 Web 安全测试,先规划再执行只读步骤",
"orchestration":"plan_execute"
}'
```
可选 `orchestration`
- `deep`
- `plan_execute`
- `supervisor`
## Recipe 5:上传附件
```bash
curl -k https://127.0.0.1:8080/api/chat-uploads \
-H "Authorization: Bearer <token>" \
-F "file=@./request.txt"
```
大文件建议上传后在消息中引用,不要直接塞进 prompt。
## Recipe 6:写入漏洞
```bash
curl -k https://127.0.0.1:8080/api/vulnerabilities \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"title":"示例 SQL 注入",
"severity":"high",
"target":"https://example.com/item?id=1",
"description":"参数 id 存在可验证 SQL 注入",
"evidence":"只读验证输出...",
"remediation":"使用参数化查询"
}'
```
字段以 OpenAPI 为准。
## Recipe 7:查询知识库
```bash
curl -k https://127.0.0.1:8080/api/knowledge/search \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"query":"SQL 注入如何判断字段数",
"riskType":"SQL Injection",
"topK":5,
"threshold":0.4
}'
```
如果结果为空,先调用 categories 看风险类型名称是否匹配。
## Recipe 8:检查外部 MCP 状态
```bash
curl -k https://127.0.0.1:8080/api/external-mcp/stats \
-H "Authorization: Bearer <token>"
```
如果服务 running 但 Agent 找不到工具,检查角色工具限制和 `tool_search`
## Recipe 9:获取工具 schema
```bash
curl -k https://127.0.0.1:8080/api/config/tools/nmap/schema \
-H "Authorization: Bearer <token>"
```
插件或自动化脚本应根据 schema 构造参数,不要猜字段名。
## Recipe 10:导出审计日志
```bash
curl -k "https://127.0.0.1:8080/api/audit/logs/export" \
-H "Authorization: Bearer <token>" \
-o audit.csv
```
导出文件可能包含敏感操作信息,应加密保存。
+239
View File
@@ -0,0 +1,239 @@
# API 参考
CyberStrikeAI 内置 OpenAPI 规格和 API 文档页面。启动服务后访问:
```text
/api-docs
```
OpenAPI JSON
```text
GET /api/openapi/spec
```
`/api/openapi/spec` 需要登录认证,避免未授权用户直接枚举接口结构。
## 认证
登录:
```http
POST /api/auth/login
Content-Type: application/json
{"password":"your-password"}
```
认证成功后,前端通常使用 Cookie 会话。外部客户端也可参考 OpenAPI 中的 Bearer Token 描述,按实际返回字段接入。
常用认证接口:
- `POST /api/auth/login`
- `POST /api/auth/logout`
- `POST /api/auth/change-password`
- `GET /api/auth/validate`
## 对话与 Agent
单代理:
- `POST /api/eino-agent`
- `POST /api/eino-agent/stream`
多代理:
- `POST /api/multi-agent`
- `POST /api/multi-agent/stream`
多代理请求体通过 `orchestration` 指定:
- `deep`
- `plan_execute`
- `supervisor`
对话管理:
- `POST /api/conversations`
- `GET /api/conversations`
- `GET /api/conversations/:id`
- `PUT /api/conversations/:id`
- `DELETE /api/conversations/:id`
- `POST /api/conversations/:id/delete-turn`
- `GET /api/messages/:id/process-details`
## 项目、漏洞、攻击链
项目:
- `GET /api/projects`
- `POST /api/projects`
- `GET /api/projects/:id`
- `PUT /api/projects/:id`
- `DELETE /api/projects/:id`
- `GET /api/projects/:id/facts`
- `POST /api/projects/:id/facts`
- `GET /api/projects/:id/fact-graph`
漏洞:
- `GET /api/vulnerabilities`
- `POST /api/vulnerabilities`
- `GET /api/vulnerabilities/:id`
- `PUT /api/vulnerabilities/:id`
- `DELETE /api/vulnerabilities/:id`
- `GET /api/vulnerabilities/export`
攻击链:
- `GET /api/attack-chain/:conversationId`
- `POST /api/attack-chain/:conversationId/regenerate`
## 工具、MCP、配置
配置:
- `GET /api/config`
- `PUT /api/config`
- `POST /api/config/apply`
- `GET /api/config/tools`
- `GET /api/config/tools/:name/schema`
- `POST /api/config/test-openai`
- `POST /api/config/test-vision`
- `POST /api/config/list-models`
MCP
- `POST /api/mcp`
- `GET /api/external-mcp`
- `PUT /api/external-mcp/:name`
- `POST /api/external-mcp/:name/start`
- `POST /api/external-mcp/:name/stop`
- `DELETE /api/external-mcp/:name`
## 知识库、Skills、角色、Agent
知识库:
- `GET /api/knowledge/categories`
- `GET /api/knowledge/items`
- `POST /api/knowledge/scan`
- `POST /api/knowledge/index`
- `POST /api/knowledge/search`
角色:
- `GET /api/roles`
- `POST /api/roles`
- `GET /api/roles/:name`
- `PUT /api/roles/:name`
- `DELETE /api/roles/:name`
Skills
- `GET /api/skills`
- `POST /api/skills`
- `GET /api/skills/:name`
- `PUT /api/skills/:name`
- `DELETE /api/skills/:name`
- `GET /api/skills/:name/files`
- `GET /api/skills/:name/file`
- `PUT /api/skills/:name/file`
Markdown 子代理:
- `GET /api/multi-agent/markdown-agents`
- `POST /api/multi-agent/markdown-agents`
- `GET /api/multi-agent/markdown-agents/:filename`
- `PUT /api/multi-agent/markdown-agents/:filename`
- `DELETE /api/multi-agent/markdown-agents/:filename`
## 高风险能力
WebShell
- `GET /api/webshell/connections`
- `POST /api/webshell/connections`
- `POST /api/webshell/exec`
- `POST /api/webshell/file`
C2
- `GET /api/c2/listeners`
- `POST /api/c2/listeners`
- `GET /api/c2/sessions`
- `POST /api/c2/tasks`
- `POST /api/c2/payloads/build`
终端:
- `POST /api/terminal/run`
- `POST /api/terminal/run/stream`
- `GET /api/terminal/ws`
这些接口应只开放给可信管理员,并配合 HTTPS、强密码、网络隔离和审计。
## 调用建议
- 优先使用 `/api-docs` 查看完整参数和响应结构。
- 流式接口使用 SSE,反向代理需关闭缓冲。
- 所有修改类接口都应处理 401、403、404、409、500。
- 外部集成建议创建最小权限网络路径,不要把 Web 管理面直接暴露到公网。
## 认证细节
认证中间件会按顺序提取 token
1. `Authorization: Bearer <token>`
2. `Authorization: <token>`
3. 查询参数 `?token=<token>`
4. Cookie `auth_token`
这意味着外部脚本最稳妥的方式是使用 `Authorization: Bearer`。查询参数虽然支持,但容易进入代理日志,不建议生产使用。
## SSE 客户端注意事项
`/api/eino-agent/stream``/api/multi-agent/stream` 是长连接。客户端应处理:
- 网络中断后不要盲目重放破坏性请求。
- 收到 `error` 事件后读取错误正文。
- 收到 `done` 才视为本轮结束。
- 代理层不能缓冲。
- 请求体中的 `conversationId` 决定是否接续已有对话。
## API 稳定性分层
| API 类型 | 稳定性 | 集成建议 |
| --- | --- | --- |
| `/api/auth/*` | 高 | 可直接集成 |
| `/api/eino-agent*` | 高 | 推荐外部对话入口 |
| `/api/openapi/spec` | 高 | 用于生成客户端 |
| `/api/config*` | 中 | 管理工具使用,谨慎自动化 |
| `/api/c2/*``/api/webshell/*` | 中 | 高风险,必须加权限边界 |
| 前端私有调用细节 | 低 | 不建议插件依赖 |
## Curl 示例
登录并提取 token 的返回字段可能随实现调整,建议先看 `/api-docs`。如果已有 token
```bash
curl -k https://127.0.0.1:8080/api/conversations \
-H "Authorization: Bearer <token>"
```
发送非流式单代理请求:
```bash
curl -k https://127.0.0.1:8080/api/eino-agent \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"message":"对 127.0.0.1 做授权的基础信息收集,先不要执行高风险操作"}'
```
## 源码锚点
- 路由:`internal/app/app.go`
- 认证:`internal/security/auth_middleware.go`
- OpenAPI`internal/handler/openapi.go`
- 单代理:`internal/handler/eino_single_agent.go`
- 多代理:`internal/handler/multi_agent.go`
+171
View File
@@ -0,0 +1,171 @@
# 架构说明
CyberStrikeAI 是一个以 Web 管理面为入口、以 Agent 和 MCP 工具为执行核心的安全测试编排平台。
## 总览
```mermaid
flowchart LR
U["Web / Robot / API 用户"] --> R["Gin Router"]
R --> H["Handlers"]
H --> DB["SQLite"]
H --> A["Agent / Multi-Agent"]
A --> M["MCP Server"]
M --> T["内置工具 / YAML 工具 / Skills FS"]
M --> EM["外部 MCP"]
A --> K["知识库检索"]
H --> W["Workflow 图编排"]
H --> C2["内置 C2"]
H --> WS["WebShell"]
H --> AU["Audit / Monitor"]
```
## Web 层
入口在 `cmd/server/`,应用组装在 `internal/app/`。Web 使用 Gin
- `web/templates/index.html`:主页面。
- `web/templates/api-docs.html`API 文档页面。
- `web/static/js/`:各业务模块前端逻辑。
- `web/static/css/`:样式。
路由注册集中在 `internal/app/app.go`
## Handler 层
`internal/handler/` 按业务拆分:
- `agent.go``eino_single_agent.go``multi_agent.go`
- `workflow.go``workflow_run.go`
- `knowledge.go`
- `webshell.go`
- `c2.go`
- `audit.go`
- `monitor.go`
- `project.go`
- `vulnerability.go`
- `config.go`
- `openapi.go`
Handler 负责参数解析、权限中间件后的业务协调和 HTTP 响应。
## Agent 层
单代理和多代理主要在:
- `internal/agent/`
- `internal/multiagent/`
- `internal/agents/`
- `agents/`
Eino ADK 提供单代理、Deep、Plan-Execute、Supervisor 等执行模式。多代理子 Agent 由 Markdown 文件定义。
## MCP 与工具
MCP 相关:
- `internal/mcp/`:Server、外部 MCP、连接恢复。
- `internal/einomcp/`Eino 与 MCP 工具适配。
- `tools/`YAML 命令工具。
- `internal/app/*_tools.go`Go 内置工具注册。
工具调用会进入监控记录,并可受 HITL 审批影响。
## Workflow
图编排在 `internal/workflow/`HTTP 入口在 `internal/handler/workflow*.go`。它支持 start、agent、tool、condition、hitl、output、end 等节点。
详细使用见 [图编排使用说明](workflow-graph.md)。
## 知识库
知识库在 `internal/knowledge/`,包括:
- Markdown/文本内容管理。
- chunk。
- embedding。
- SQLite 向量索引。
- multi-query。
- rerank。
- 检索日志。
启用后会向 Agent 暴露知识检索工具。
## 数据层
`internal/database/` 封装 SQLite 访问,保存:
- 对话、消息、过程详情。
- 分组。
- 工具执行记录。
- HITL 日志。
- 知识库索引和检索日志。
- WebShell、C2、项目、漏洞、批量任务等业务数据。
默认数据库文件:
- `data/conversations.db`
- `data/knowledge.db`
## 安全与审计
`internal/security/` 提供认证、限流、Shell 执行和命令流处理。`internal/audit/``internal/monitor/` 分别负责平台审计和执行监控。
高风险模块包括:
- Terminal。
- WebShell。
- C2。
- 外部 MCP。
- 文件系统和 Shell Skills。
这些模块应结合角色、HITL 和部署隔离使用。
## 一次对话请求的真实路径
`/api/eino-agent/stream` 为例:
1. Gin 路由进入认证中间件。
2. Handler 解析请求体、会话 ID、角色、附件和 WebShell 上下文。
3. Agent 构建模型输入,包括历史消息、角色提示、项目事实、工具列表。
4. Eino Runner 调用模型。
5. 模型需要工具时走 MCP Tool。
6. 工具调用前可能触发 HITL。
7. 工具执行结果写入过程详情和监控。
8. 模型继续推理并生成最终回答。
9. SSE 将进度、工具事件、文本增量推给前端。
10. 会话、消息、过程详情写入 SQLite。
这个路径解释了为什么问题可能出在很多层:认证、会话、模型、工具、HITL、MCP、数据库、SSE 或前端渲染。
## 横向模块依赖
几个模块不是独立页面,而是横向能力:
- Project facts:会被注入 Agent 上下文,影响多轮和跨对话判断。
- HITL:插在工具调用前,影响所有 Agent/MCP 工具。
- Monitor:记录工具执行,影响任务取消、复盘和通知。
- Audit:记录平台管理动作,影响安全运营。
- Tool search:影响模型看见哪些工具,而不仅仅是工具页面显示。
改这些模块时要看全局调用点,不要只测单个页面。
## 复杂度热点
维护时优先警惕:
- `internal/app/app.go`:组装所有服务,容易引入初始化顺序问题。
- `internal/handler/config.go`:热应用配置,影响模型、知识库、C2、机器人和 MCP。
- `internal/multiagent/`:中间件多,流式、重试、摘要和工具调用交错。
- `internal/security/`Shell 和认证是安全边界。
- `internal/database/`:SQLite 结构演进必须兼容旧数据。
## 设计取舍
项目选择单体 Go 服务 + SQLite + 静态前端,是为了降低部署门槛。但代价是:
- 多实例横向扩展不天然成立,尤其 SQLite 写入和内存 session。
- 运行态配置和本地文件强绑定,需要良好备份。
- 高权限工具和 Web 管理面在同一进程内,部署隔离更重要。
这些不是缺陷,而是部署时必须理解的边界。
+148
View File
@@ -0,0 +1,148 @@
# 审计与监控
CyberStrikeAI 有两类常用可观测数据:平台操作审计和工具执行监控。二者用途不同,建议同时开启。
## 平台审计
配置:
```yaml
audit:
enabled: true
retention_days: 15
max_detail_bytes: 8192
auth_failure_cooldown_seconds: 60
```
审计记录覆盖登录、配置、资源管理等平台操作。它不会完整记录对话正文,也不逐条记录所有工具调用正文。
接口:
- `GET /api/audit/meta`
- `GET /api/audit/summary`
- `GET /api/audit/logs`
- `GET /api/audit/logs/:id`
- `GET /api/audit/logs/export`
建议关注:
- 登录失败和异常来源 IP。
- 密码修改。
- 配置修改。
- 外部 MCP 增删改。
- C2/WebShell/知识库等高风险资源操作。
## 工具执行监控
配置:
```yaml
monitor:
retention_days: 90
```
工具执行监控用于查看 MCP 工具调用、命令状态、耗时、取消和结果摘要。
接口:
- `GET /api/monitor`
- `GET /api/monitor/execution/:id`
- `POST /api/monitor/execution/:id/cancel`
- `DELETE /api/monitor/execution/:id`
- `DELETE /api/monitor/executions`
- `GET /api/monitor/stats`
- `GET /api/monitor/calls-timeline`
- `POST /api/monitor/executions/names`
## 通知摘要
接口:
- `GET /api/notifications/summary`
- `POST /api/notifications/read`
通知用于提示待处理事项、未读状态或运行中任务概况。具体展示取决于前端页面。
## HITL 日志
HITL 决策日志独立管理:
- `GET /api/hitl/pending`
- `GET /api/hitl/logs`
- `GET /api/hitl/logs/:id`
- `DELETE /api/hitl/logs`
- `POST /api/hitl/decision`
- `POST /api/hitl/dismiss`
建议将 HITL 日志与平台审计结合,用于复盘 Agent 为什么执行或没有执行某个工具。
## 保留策略
建议:
- 审计日志保留 15 到 90 天,按组织要求调整。
- 工具执行记录保留 30 到 180 天。
- C2、WebShell、上传附件和任务结果按项目周期单独清理。
- 导出日志时注意脱敏和访问权限。
## 运维巡检
每周检查:
- 是否有异常登录失败。
- 是否有未授权配置变更。
- 长时间运行或失败率高的工具。
- 外部 MCP 连接状态。
- 数据库文件大小和磁盘空间。
每次演练结束:
- 导出必要审计证据。
- 删除无用 WebShell/C2 会话和 payload。
- 清理上传附件和临时工作区。
- 归档报告、漏洞和项目事实。
## 审计和监控的边界
两者经常被混用,但语义不同:
- 审计回答“谁在平台上做了什么管理动作”。
- 监控回答“工具调用运行得怎么样”。
- HITL 日志回答“某个工具调用为什么被放行、修改或拒绝”。
- 对话过程详情回答“Agent 当时如何推理和串联步骤”。
一次安全复盘通常要把四类信息合在一起看。只看审计,会漏掉具体工具输出;只看监控,会漏掉谁修改了配置。
## 关键事件解释
建议重点关注这些事件类型:
| 事件 | 为什么重要 |
| --- | --- |
| 登录失败 | 暴力尝试、密码泄露或误配置 |
| 修改密码 | 所有旧 session 会被撤销,可能影响正在使用的人 |
| 更新配置 | 可能改变模型、工具、C2、知识库、审计策略 |
| 外部 MCP 变更 | 新工具可能拥有本机或远端执行能力 |
| C2 listener/task | 直接影响授权目标和网络暴露面 |
| WebShell 连接变更 | 可能引入真实业务系统执行通道 |
| HITL 拒绝 | 说明 Agent 或用户请求触达风险边界 |
## 日志保留不是越久越好
安全工具日志往往包含目标、漏洞、路径、命令输出和组织内部信息。保留时间应平衡复盘价值与泄露风险:
- 短期演练:15-30 天。
- 持续红队平台:90-180 天。
- 合规要求:按组织规范归档,但导出后应加密。
如果没有专门日志平台,不要无限期保留 SQLite 中的所有明细。
## 源码锚点
- 审计服务:`internal/audit/service.go`
- 审计脱敏:`internal/audit/sanitize.go`
- 审计保留:`internal/audit/retention.go`
- 审计接口:`internal/handler/audit.go`
- 监控 reconcile`internal/monitor/reconcile.go`
- 监控接口:`internal/handler/monitor.go`
- HITL 日志:`internal/handler/hitl_logs.go`
+172
View File
@@ -0,0 +1,172 @@
# 内置 C2 使用说明
内置 C2 用于授权环境中的会话管理、任务下发、payload 生成和结果回收。不使用时建议关闭。
```yaml
c2:
enabled: false
```
## 功能组成
主要对象:
- Listener:监听器,负责接收会话。
- Session:上线会话。
- Task:下发给会话的任务。
- Payload:生成的载荷或 one-liner。
- Profile:通信配置模板。
- Event:监听器、会话、任务产生的事件。
- File:给 implant 下载或任务结果回收的文件。
Web API 前缀是 `/api/c2`。关闭 C2 时接口返回 `503 c2_disabled`
## 监听器
常用接口:
- `GET /api/c2/listeners`
- `POST /api/c2/listeners`
- `POST /api/c2/listeners/:id/start`
- `POST /api/c2/listeners/:id/stop`
- `DELETE /api/c2/listeners/:id`
建议给监听器使用清晰命名,标明演练项目、网络区域和授权范围。
## 会话
常用接口:
- `GET /api/c2/sessions`
- `GET /api/c2/sessions/:id`
- `PUT /api/c2/sessions/:id/sleep`
- `DELETE /api/c2/sessions/:id`
`sleep` 用于调整会话轮询间隔。间隔越短,交互越实时,但流量和暴露面更高。
## 任务
常用接口:
- `GET /api/c2/tasks`
- `POST /api/c2/tasks`
- `POST /api/c2/sessions/:id/tasks`
- `POST /api/c2/tasks/:id/cancel`
- `GET /api/c2/tasks/:id/wait`
- `GET /api/c2/tasks/:id/result-file`
任务应和授权目标一致。高风险任务建议走 HITL,并在审计日志中保留操作痕迹。
## Payload
常用接口:
- `POST /api/c2/payloads/oneliner`
- `POST /api/c2/payloads/build`
- `GET /api/c2/payloads/:id/download`
生成前确认:
- 回连地址是否正确。
- 平台和架构是否匹配。
- 是否需要代理、sleep、profile。
- 文件是否只在授权环境分发。
## 文件
常用接口:
- `POST /api/c2/files/upload`
- `GET /api/c2/files`
- `GET /api/c2/tasks/:id/result-file`
上传文件可供 implant 下载。结果文件可能包含敏感信息,应按项目保密级别保存和清理。
## MCP 工具
C2 启用后会注册相关 MCP 工具,供 Agent 管理监听器、会话、任务、payload 等。建议:
- 不把 C2 工具加入全局免审批白名单。
- 在角色提示词中限制项目、目标、任务类型。
- 对执行命令、上传文件、生成 payload 的步骤开启人工审批。
## 安全建议
- 仅在授权环境启用。
- 不在公网暴露管理 Web。
- Listener 暴露端口与 Web 管理端口分离。
- 定期清理会话、任务、payload 和事件。
- 演练结束后关闭监听器并删除无用 payload。
- 保留必要审计证据,但不要长期保存敏感输出。
## 排错
监听器无法启动:
- 端口被占用。
- 权限不足,低端口需要额外权限。
- 防火墙或安全组未放行。
会话不上线:
- payload 回连地址错误。
- 目标无法访问监听器。
- TLS/Profile 不匹配。
- 被安全产品阻断。
任务无结果:
- 会话 sleep 较长。
- 会话已离线。
- 命令在目标端卡住。
- 结果过大,需要通过结果文件下载。
## 生命周期视角
C2 的正确使用不是“创建 listener 然后下命令”,而是一个生命周期:
1. 授权确认:项目、目标、时间窗口、允许动作。
2. Profile 设计:通信方式、sleep、回连地址、文件通道。
3. Listener 启动:确认端口、网络路径和日志。
4. Payload 生成:记录 hash、用途、投递方式。
5. Session 接入:确认目标身份、权限和环境。
6. Task 下发:只执行与授权目标一致的任务。
7. 结果归档:必要输出写入项目事实或报告。
8. 清理:停止 listener、删除 payload、清理 session/task/event。
跳过前两步会导致后续每个操作都不可审计。
## 任务分级
| 等级 | 示例 | 审批建议 |
| --- | --- | --- |
| L1 只读识别 | `whoami`、主机名、当前目录 | 可由审计 Agent 放行 |
| L2 环境枚举 | 网络接口、进程、用户组 | 建议人工或严格审计 |
| L3 文件访问 | 读取配置、下载结果文件 | 人工确认目标和路径 |
| L4 执行变更 | 上传文件、修改 sleep、运行脚本 | 人工审批 |
| L5 持久化/横向/破坏 | 自启、凭证、删除、加密、扩散 | 默认拒绝,除非授权明确 |
把这个分级写进 HITL 提示词,比单纯“危险则拒绝”更可操作。
## 事件复盘
一次 C2 操作复盘至少回答:
- 哪个 listener 接收了哪个 session
- payload 是谁生成的,什么时候生成的?
- session 属于哪个授权目标?
- 下发了哪些 task
- task 输出是否写入报告或项目事实?
- 是否停止 listener 并清理 payload
如果这些问题答不上来,说明 C2 过程管理还不够闭环。
## 源码锚点
- C2 Manager`internal/c2/manager.go`
- Listener`internal/c2/listener.go`
- HTTP Listener`internal/c2/listener_http.go`
- TCP Listener`internal/c2/listener_tcp.go`
- Payload`internal/c2/payload_builder.go`
- Handler`internal/handler/c2.go`
- MCP 工具:`internal/app/c2_tools.go`
+194
View File
@@ -0,0 +1,194 @@
# 配置画像
[English](../en-US/configuration-profiles.md)
本文给出几套常用配置画像。它们不是完整 `config.yaml`,而是部署时最容易影响安全和可用性的关键段落。
## 本地开发画像
目标:方便调试,允许较多本地能力。
常用启动:
```bash
chmod +x run.sh && ./run.sh
```
```yaml
server:
host: 127.0.0.1
port: 8080
tls_enabled: true
tls_auto_self_sign: true
auth:
password: "dev-only-change-me"
audit:
enabled: true
retention_days: 7
c2:
enabled: false
multi_agent:
enabled: true
eino_skills:
filesystem_tools: true
```
适用:
- 本地功能开发。
- 调试前端和 Handler。
- 调试 Skills、本地文件工具。
不适用:
- 多人共享。
- 公网访问。
## 内网团队画像
目标:团队共享,保留审计,限制高风险能力。
```yaml
server:
host: 127.0.0.1
port: 8080
tls_enabled: false
auth:
password: "<long-random-password>"
audit:
enabled: true
retention_days: 30
monitor:
retention_days: 90
c2:
enabled: false
mcp:
enabled: false
hitl:
default_reviewer: human
tool_whitelist: [read_file, glob, grep, tool_search]
```
配合:
- Nginx/Traefik 终止 HTTPS。
- 反向代理 IP 白名单。
- 定期备份 `data/`
## 只启用知识库画像
目标:把 CyberStrikeAI 作为知识增强助手,尽量关闭攻击面。
```yaml
c2:
enabled: false
mcp:
enabled: false
knowledge:
enabled: true
base_path: knowledge_base
retrieval:
top_k: 5
similarity_threshold: 0.4
multi_agent:
eino_skills:
filesystem_tools: false
```
建议:
- 角色只绑定知识库和只读工具。
- 禁用外部 MCP。
- 不保存真实客户敏感材料。
## 高审计生产画像
目标:生产红队或长期安全平台。
```yaml
auth:
password: "<managed-secret>"
session_duration_hours: 8
audit:
enabled: true
retention_days: 90
max_detail_bytes: 8192
monitor:
retention_days: 180
hitl:
default_reviewer: human
retention_days: 180
tool_whitelist: [read_file, glob, grep, tool_search]
c2:
enabled: false
multi_agent:
eino_callbacks:
enabled: true
mode: log_only
sse_trace_to_client: false
```
配合:
- 反向代理认证。
- 独立运行用户。
- 日志采集。
- 备份加密。
- 明确项目结束清理流程。
## C2 演练画像
目标:只在授权演练窗口临时启用 C2。
```yaml
c2:
enabled: true
hitl:
default_reviewer: human
tool_whitelist: [read_file, glob, grep, tool_search]
audit:
enabled: true
monitor:
retention_days: 180
```
操作要求:
- 演练前确认授权范围。
- Listener 端口和 Web 管理端口分离。
- 演练结束执行 C2 清理 Runbook。
- 结束后恢复 `c2.enabled: false`
## 外部 MCP 自动化画像
目标:接入可信的内部工具服务。
```yaml
external_mcp:
servers: {}
multi_agent:
eino_middleware:
tool_search_enable: true
tool_search_min_tools: 20
hitl:
default_reviewer: audit_agent
tool_whitelist: [read_file, glob, grep, tool_search]
```
建议:
- 每个 MCP 工具都写清楚 schema。
- 高风险 MCP 工具不进白名单。
- stdio MCP 用独立工作目录。
- HTTP MCP 必须有认证。
## 画像选择决策
| 需求 | 选择 |
| --- | --- |
| 单人开发 | 本地开发画像 |
| 多人内网使用 | 内网团队画像 |
| 文档/知识问答 | 只启用知识库画像 |
| 长期生产平台 | 高审计生产画像 |
| 授权 C2 演练 | C2 演练画像 |
| 接内部工具平台 | 外部 MCP 自动化画像 |
+275
View File
@@ -0,0 +1,275 @@
# 配置参考
CyberStrikeAI 的主配置文件是 `config.yaml`。大多数配置也可以在 Web 的“系统设置”中修改,保存后再应用。生产环境中,建议把敏感值放在受控配置系统中,并限制 `config.yaml` 的文件权限。
## 基础配置
```yaml
version: "v1.6.51"
server:
host: 0.0.0.0
port: 8080
tls_enabled: true
tls_auto_self_sign: true
auth:
password: "change-me"
session_duration_hours: 12
log:
level: info
output: stdout
```
- `version`:前端展示版本。
- `server.host/port`Web 服务监听地址和端口。
- `server.tls_*`HTTPS 配置。生产环境建议使用 `tls_cert_path``tls_key_path`
- `auth.password`Web 登录密码,必须改为强密码。
- `auth.session_duration_hours`:登录会话有效期。
- `log.output`:可以是 `stdout``stderr` 或文件路径。
## 模型配置
```yaml
openai:
provider: openai
base_url: https://api.openai.com/v1
api_key: sk-...
model: gpt-4.1
max_total_tokens: 120000
reasoning:
mode: on
effort: high
allow_client_reasoning: true
profile: openai_compat
```
- `provider``openai` 表示 OpenAI 兼容接口;`claude` 会桥接到 Anthropic Claude Messages API。
- `base_url/api_key/model`:主模型配置。
- `max_total_tokens`:上下文压缩、攻击链构建、多代理摘要等共用的总预算。
- `reasoning`:控制推理扩展字段。不同网关支持差异较大,异常时先尝试 `mode: off`
## Agent
```yaml
agent:
max_iterations: 12000
tool_timeout_minutes: 60
shell_no_output_timeout_seconds: 1200
workspace_root_dir: ""
system_prompt_path: ""
```
- `max_iterations`:单代理、多代理主执行器和子代理的默认迭代上限。
- `tool_timeout_minutes`:单次工具最长运行时间。
- `shell_no_output_timeout_seconds`Shell 长时间无输出时终止。
- `workspace_root_dir`:会话工作区根目录,建议不要设置到系统 `/tmp`
- `system_prompt_path`:单代理系统提示词覆盖文件。
## HITL
```yaml
hitl:
default_reviewer: audit_agent
retention_days: 90
tool_whitelist: [read_file, list_dir, glob, grep, tool_search]
audit_model:
provider: ""
base_url: ""
api_key: ""
model: ""
```
- `default_reviewer``human``audit_agent`
- `tool_whitelist`:全局免审批工具列表,会与会话白名单合并。
- `audit_model`:审计 Agent 独立模型;留空复用主模型。
- `audit_agent_prompt` / `audit_agent_prompt_review_edit`:可覆盖默认审批策略。
更多策略见 [人机协同最佳实践](hitl-best-practices.md)。
## 多代理
```yaml
multi_agent:
enabled: true
robot_default_agent_mode: eino_single
batch_use_multi_agent: false
eino_skills:
disable: false
filesystem_tools: true
skill_tool_name: skill
```
支持模式:
- `eino_single`Eino 单代理。
- `deep`DeepAgent 风格多代理。
- `plan_execute`:规划、执行、重规划。
- `supervisor`:主管代理转交子代理。
`agents_dir` 指向 Markdown 子代理目录。单个代理可在 front matter 中设置 `tools``bind_role``max_iterations`
## 工具与 MCP
```yaml
security:
tools_dir: tools
tool_description_mode: full
mcp:
enabled: false
host: 0.0.0.0
port: 8081
auth_header: "X-MCP-Token"
auth_header_value: ""
external_mcp:
servers: {}
```
- `security.tools_dir`:内置工具 YAML 目录。
- `tool_description_mode``short` 更省 token`full` 更完整。
- `mcp.enabled`:是否启动独立 HTTP MCP 服务。
- `mcp.auth_header_value`:外部调用 MCP 时的共享密钥,生产环境必须设置。
- `external_mcp.servers`:外部 MCP 联邦配置。
工具 YAML 规则见 `tools/README.md`
## 知识库
```yaml
knowledge:
enabled: false
base_path: knowledge_base
embedding:
provider: openai
model: text-embedding-v4
base_url: ""
api_key: ""
retrieval:
top_k: 5
similarity_threshold: 0.4
indexing:
chunk_size: 512
chunk_overlap: 50
batch_size: 10
```
启用后会注册知识库检索工具,并开放管理接口。详细说明见 [知识库](knowledge-base.md)。
## 数据库
```yaml
database:
path: data/conversations.db
knowledge_db_path: data/knowledge.db
```
默认使用 SQLite。`knowledge_db_path` 为空时可复用会话数据库;独立文件更便于迁移知识库。
## 审计与监控
```yaml
audit:
enabled: true
retention_days: 15
max_detail_bytes: 8192
monitor:
retention_days: 90
```
- `audit` 记录平台操作,不记录对话正文和每次工具调用正文。
- `monitor` 管理工具执行记录保留时间。
## C2、WebShell、项目
```yaml
c2:
enabled: true
project:
enabled: true
fact_index_max_runes: 65000
```
- `c2.enabled`:关闭后不启动 C2 监听器,也不注册 C2 MCP 工具。
- WebShell 连接配置存 SQLite,没有单独的主配置开关。
- `project` 控制跨对话事实黑板注入预算。
## 机器人
`robots` 支持个人微信 iLink、企业微信、钉钉、飞书、Telegram、Slack、Discord、QQ。详细配置步骤见 [机器人使用说明](robot.md)。
## 配置修改建议
- 先在测试环境验证模型、MCP、知识库和高风险工具。
- 改动 `tools_dir``roles_dir``skills_dir``agents_dir` 后,检查 Web 页面是否能列出对应资源。
- 生产环境避免开启不需要的 C2、WebShell、终端和外部 MCP。
- 修改敏感配置后,检查审计页面是否有异常登录或配置变更记录。
## 配置应用机制
配置不是所有字段都同等“热更新”。`/api/config/apply` 会做一组协调动作:更新模型配置、工具描述模式、重新注册部分 MCP 工具、初始化或更新知识库、重启机器人连接、按配置启停 C2。这个逻辑在 `internal/handler/config.go` 中由 `ConfigHandler` 协调。
实务判断:
| 配置段 | 应用后通常立即生效 | 需要额外动作 |
| --- | --- | --- |
| `openai` | 新请求使用新模型配置 | 旧的流式请求不会被强制切换 |
| `agent.max_iterations` | 新 Agent 任务生效 | 已运行任务按启动时状态继续 |
| `security.tool_description_mode` | 工具重新暴露时生效 | 模型已有上下文不会回滚 |
| `hitl.tool_whitelist` | 新工具调用审批判断生效 | 已挂起审批不自动重判 |
| `knowledge.enabled` | 会尝试初始化/更新组件 | 启用后仍需扫描和索引 |
| `knowledge.embedding` | 检索器/索引器配置更新 | 已有向量通常需要重建索引 |
| `robots` | 会触发连接重启 | 平台回调配置仍需在平台侧正确 |
| `c2.enabled` | 会协调 C2 runtime | 已暴露端口和会话要人工确认 |
| `server.port/tls` | 通常需要重启进程 | 监听地址不是普通热更新 |
## 配置优先级和派生关系
几个字段有“留空复用”的关系:
- `vision.api_key/base_url/provider` 留空时复用 `openai`
- `hitl.audit_model` 留空时复用 `openai`
- `knowledge.embedding.base_url/api_key` 留空时复用主模型或 embedding 默认配置。
- `knowledge.retrieval.rerank.base_url/api_key` 留空时复用 embedding/openai。
- `database.knowledge_db_path` 留空时可以复用主会话数据库,但独立文件更利于备份。
这类配置排障时不要只看子配置段,也要看它会回落到哪个上级配置。
## 参数取值建议
| 参数 | 保守值 | 激进值 | 判断依据 |
| --- | --- | --- | --- |
| `agent.tool_timeout_minutes` | 10-30 | 60+ | 扫描工具是否常跑长任务 |
| `shell_no_output_timeout_seconds` | 300-600 | 1200+ | 工具是否长时间静默 |
| `knowledge.indexing.batch_size` | 5-10 | 20+ | embedding 服务批量限制 |
| `knowledge.indexing.rate_limit_delay_ms` | 300-800 | 0-100 | 服务商 RPM 和 429 情况 |
| `retrieval.top_k` | 3-5 | 8-12 | 内容质量和上下文预算 |
| `similarity_threshold` | 0.35-0.45 | 0.5+ | 召回优先还是精度优先 |
| `audit.retention_days` | 15-30 | 90+ | 合规要求和磁盘空间 |
| `monitor.retention_days` | 30-90 | 180+ | 是否需要长周期复盘 |
## 变更前后验证模板
修改配置前记录:
```text
变更目的:
涉及配置段:
预期影响:
回滚方式:
验证接口:
```
修改后验证:
```bash
curl -k https://127.0.0.1:8080/api/auth/validate \
-H "Authorization: Bearer <token>"
```
再按配置类型验证模型、工具、知识库、C2 或机器人。不要只看 Web 保存成功提示。
## 源码锚点
- 配置结构:`internal/config/config.go`
- 环境变量展开:`internal/config/envexpand.go`
- Web 配置接口:`internal/handler/config.go`
- 路由注册:`internal/app/app.go`
- C2 配置协调:`internal/app/c2_lifecycle.go`
+115
View File
@@ -0,0 +1,115 @@
# 贡献规范
[English](../en-US/contributing-guide.md)
本文定义向 CyberStrikeAI 增加功能、接口、工具、前端页面或文档时的基本要求。
## 总原则
- 新功能要有文档入口。
- 新 API 要更新 OpenAPI。
- 新前端文案要补中英文 i18n。
- 新配置要说明是否支持热应用。
- 新高风险工具要说明 HITL 策略。
- 新数据库字段要兼容旧库。
- 新长任务要有状态、取消或恢复策略。
## 新增 API Checklist
- Handler 参数校验明确。
- 错误响应包含稳定 `error` 和可读 `message`
- 接口受认证保护,除非明确是平台回调。
- 修改类接口写审计。
- 长任务写监控或任务状态。
- 更新 `internal/handler/openapi.go`
- 更新 API 文档或 Recipe。
- 增加 Handler 测试。
## 新增配置 Checklist
- `config.Config` 结构体有字段。
- `config.yaml` 示例有注释。
- 省略字段时有安全默认值。
- 旧配置能启动。
- 说明是否热应用。
- Web 设置页不会误删未知字段。
- 如影响高风险能力,更新安全文档。
## 新增工具 Checklist
适用于 YAML 工具和 Go 内置 MCP 工具。
- 工具名稳定、具体、避免重名。
- `short_description` 能被 `tool_search` 搜到。
- 输入 schema 明确,不用裸 `cmd` 包所有行为。
- 输出可读且结构稳定。
- 超时和错误路径可控。
- 高风险操作不进全局白名单。
- 文档说明使用场景和风险。
## 新增前端页面 Checklist
- 复用现有 `apiFetch`、modal、通知和状态样式。
- 所有可见文案补 `zh-CN.json``en-US.json`
- 有 loading、empty、error 状态。
- 删除/高风险操作有确认。
- 长文本和英文按钮不溢出。
- 浏览器控制台无错误。
## 新增数据库变更 Checklist
- 迁移幂等。
- 旧库可升级。
- 字段默认值合理。
- 大表索引谨慎。
- 测试空库和旧库。
- 发布说明提醒备份。
## 新增高风险能力 Checklist
高风险包括:Shell、WebShell、C2、外部 MCP 写入/执行、凭证访问、批量扫描。
必须回答:
- 谁能调用?
- 是否需要 HITL
- 审计记录什么?
- 如何取消?
- 如何清理?
- 如何禁用?
- 默认是否关闭?
## 文档要求
每个重要功能至少补:
- 用途。
- 配置。
- 操作流程。
- 风险边界。
- 排错。
- 源码锚点。
中英文文档要保持文件名一致,分别放在:
```text
docs/zh-CN/
docs/en-US/
```
更新导航:
- `docs/README.md`
- `docs/zh-CN/README.md`
- `docs/en-US/README.md`
## Review 关注点
代码评审优先看:
- 行为回归。
- 安全边界。
- 旧数据兼容。
- 错误处理。
- 测试缺口。
- 文档和 OpenAPI 是否同步。
+249
View File
@@ -0,0 +1,249 @@
# 部署指南
本文说明 CyberStrikeAI 的常见部署方式。生产环境部署前,请先阅读 [安全模型](security-model.md),确认授权范围、认证、HITL、审计和高风险功能开关。
## 部署前准备
基础依赖:
- Go:用于源码运行或构建二进制。
- Python:部分 MCP 服务或工具脚本需要 Python 运行环境。
- SQLite:默认使用文件型数据库,无需单独服务。
- 安全工具:`tools/` 中的 YAML 只是工具定义,实际命令如 `nmap``sqlmap``nuclei` 仍需安装到系统 PATH。
- 模型服务:需要 OpenAI 兼容 API,或配置 `openai.provider: claude` 走 Claude 桥接。
建议目录:
```text
CyberStrikeAI-main/
config.yaml
data/
tools/
roles/
skills/
agents/
knowledge_base/
```
`data/``config.yaml`、自定义 `tools/roles/skills/agents/knowledge_base` 是最重要的持久化内容,升级前应备份。
## 快速启动
仓库提供 `run.sh`,适合本地体验和小规模部署:
```bash
chmod +x run.sh && ./run.sh
```
默认配置中 `server.tls_enabled: true``tls_auto_self_sign: true`,访问地址通常是:
```text
https://127.0.0.1:8080/
```
自签证书会触发浏览器安全提示,这是本地测试的正常现象。生产环境建议配置真实证书。
`run.sh` 是最常用的启动入口,适合:
- 本机体验。
- 开发调试。
- 小团队临时内网使用。
- 升级后快速验证新版是否能启动。
如果需要长期运行、开机自启、日志托管或进程崩溃自动恢复,建议改用 systemd 托管二进制。
## 源码运行
适合开发调试:
```bash
go run ./cmd/server --config config.yaml
```
如果依赖下载较慢,可以先配置 Go 代理:
```bash
go env -w GOPROXY=https://goproxy.cn,direct
```
## 构建二进制
```bash
go build -o cyberstrike-ai ./cmd/server
./cyberstrike-ai --config config.yaml
```
交付二进制时仍需要携带:
- `web/templates/`
- `web/static/`
- `tools/`
- `roles/`
- `skills/`
- `agents/`
- `config.yaml`
## HTTPS
本地测试可以使用自签:
```yaml
server:
tls_enabled: true
tls_auto_self_sign: true
```
生产环境建议使用证书文件:
```yaml
server:
host: 0.0.0.0
port: 8080
tls_enabled: true
tls_cert_path: /etc/letsencrypt/live/example.com/fullchain.pem
tls_key_path: /etc/letsencrypt/live/example.com/privkey.pem
```
启用 TLS 后,同端口 HTTP 请求默认会 308 跳转到 HTTPS。若前面有反向代理负责 TLS,可以关闭应用内 TLS,在代理层处理 HTTPS。
## 反向代理
Nginx 示例:
```nginx
server {
listen 443 ssl http2;
server_name cyberstrike.example.com;
ssl_certificate /etc/letsencrypt/live/cyberstrike.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/cyberstrike.example.com/privkey.pem;
client_max_body_size 200m;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_buffering off;
}
}
```
`proxy_buffering off` 对 SSE 流式输出和 WebSocket 终端更友好。
## systemd
示例服务:
```ini
[Unit]
Description=CyberStrikeAI
After=network.target
[Service]
Type=simple
WorkingDirectory=/opt/CyberStrikeAI
ExecStart=/opt/CyberStrikeAI/cyberstrike-ai --config /opt/CyberStrikeAI/config.yaml
Restart=on-failure
RestartSec=5
Environment=GIN_MODE=release
[Install]
WantedBy=multi-user.target
```
启用:
```bash
sudo systemctl daemon-reload
sudo systemctl enable --now cyberstrikeai
sudo journalctl -u cyberstrikeai -f
```
## 数据与备份
重点备份:
- `config.yaml`
- `data/conversations.db`
- `data/knowledge.db`
- `data/eino-checkpoints/`
- 自定义 `tools/roles/skills/agents/knowledge_base`
- 上传文件目录 `chat_uploads/`
SQLite 热备份时最好先停止服务,或至少复制 `*.db``*.db-wal``*.db-shm` 三类文件。
## 升级
推荐流程:
1. 停止服务。
2. 备份 `config.yaml``data/` 和自定义目录。
3. 拉取或替换新版代码/二进制。
4. 保留原配置,按新版 `config.yaml` 示例补新增字段。
5. 启动服务,检查登录、模型测试、工具列表、知识库状态。
仓库提供 `upgrade.sh`,适合无兼容性问题的快速升级;生产环境仍建议先备份再运行。
## 回滚
回滚时同时恢复:
- 上一版本二进制或代码。
- 升级前的 `config.yaml`
- 升级前的 `data/`
如果新版已经写入数据库结构变更,单独回滚二进制可能不够,建议整体恢复备份。
## 生产部署决策表
| 场景 | 推荐部署 | 关键配置 | 不建议 |
| --- | --- | --- | --- |
| 单人本机测试 | `./run.sh` + 自签 HTTPS | `tls_auto_self_sign: true` | 暴露公网 |
| 小团队内网 | 二进制 + systemd + 内网 HTTPS | 强密码、审计、备份、限制来源 IP | 所有人共用弱密码 |
| 生产红队平台 | 反向代理 + 独立运行用户 + 日志采集 | 真实证书、反向代理认证、C2 按需启用 | Web 管理面直连公网 |
| 只做知识库/对话 | 关闭 C2,禁用不需要的外部 MCP | `c2.enabled: false` | 默认开启所有高风险模块 |
| 多工具自动化 | 独立工作目录 + HITL + 工具白名单 | `workspace_root_dir``hitl``monitor` | 让 Agent 拥有全局 Shell 权限且免审批 |
## 运行时文件分层
部署时最容易出问题的是“代码、配置、运行数据混在一起”。建议按下面方式理解:
- 可替换:二进制、`web/`、默认 `tools/roles/skills/agents/docs`
- 必须保留:`config.yaml``data/`、自定义工具/角色/技能/子代理、`knowledge_base/``chat_uploads/`
- 可清理但要谨慎:`data/eino-checkpoints/`、临时 workspace、旧 payload、旧工具执行记录。
升级时如果覆盖整个目录,应先把自定义目录和 `data/` 移出或备份。很多“升级后配置丢了”的问题,本质是把运行态文件当成发布包的一部分覆盖掉。
## 启动后验收清单
启动成功不代表可用,至少做下面检查:
1. 打开 `/`,确认 HTTPS/反向代理没有跳转循环。
2. 登录后访问 `/api/auth/validate`,确认会话可用。
3. 系统设置中执行模型测试。
4. 打开工具列表,确认 `tools/` 被加载,核心工具 schema 正常。
5. 若启用知识库,访问知识库页,确认 `index-status` 正常。
6. 若启用外部 MCP,查看外部 MCP 状态和工具是否出现在对话侧。
7. 若启用 C2,只在授权网络启动一个测试 listener,并确认停止/删除正常。
8. 查看审计页面,确认登录和配置读取有记录。
## 反向代理容易踩的坑
- SSE 被缓冲:表现为 Agent 一直不输出,结束时一次性吐出。关闭 `proxy_buffering`
- WebSocket 失败:终端或事件流异常。检查 `Upgrade``Connection` 头。
- HTTPS 混用:应用内 TLS 和 Nginx TLS 同时启用时,`proxy_pass` 协议必须匹配。
- 上传失败:调大 `client_max_body_size`,并检查应用侧上传限制。
- 308 循环:如果应用启用同端口 HTTPS 跳转,而代理又用 HTTP 回源,需要关闭应用 TLS 或改代理回源 HTTPS。
## 源码锚点
- 服务组装和路由:`internal/app/app.go`
- HTTPS 和自签证书:`internal/app/main_server_tls.go`
- HTTP 到 HTTPS 跳转:`internal/app/main_server_http_redirect.go`
- 配置结构和默认值:`internal/config/config.go`
- 配置应用逻辑:`internal/handler/config.go`
+178
View File
@@ -0,0 +1,178 @@
# 开发者指南
本文面向二次开发者,说明项目结构、启动方式、主要扩展点和开发习惯。
## 项目结构
```text
cmd/server/ Web 服务入口
internal/app/ 应用组装、路由注册、MCP 工具注册
internal/handler/ HTTP Handler
internal/database/ SQLite 数据访问
internal/security/ 认证、限流、Shell 执行
internal/mcp/ MCP Server、外部 MCP 管理
internal/multiagent/ Eino 单代理、多代理、中间件
internal/workflow/ 图编排运行时
internal/knowledge/ 知识库索引与检索
internal/c2/ 内置 C2
internal/project/ 项目事实黑板
web/static/ 前端 JS/CSS/资源
web/templates/ HTML 模板
tools/ 命令工具 YAML
roles/ 角色 YAML
agents/ 多代理 Markdown 定义
skills/ Agent Skills
docs/ 项目文档
```
## 启动开发环境
```bash
go run ./cmd/server --config config.yaml
```
前端是静态页面,模板在 `web/templates/`JS/CSS 在 `web/static/`。修改后刷新浏览器即可验证,多数场景不需要单独前端构建。
## 路由
路由集中在 `internal/app/app.go``registerRoutes` 中。新增业务接口通常需要:
1.`internal/handler/` 增加 Handler。
2.`internal/database/` 增加必要的数据访问。
3.`internal/app/app.go` 构造并注册路由。
4. 如需对外文档,更新 `internal/handler/openapi.go`
5. 如需前端调用,更新 `web/static/js/`
## 数据库
默认 SQLite。新增表或字段时:
- 将迁移逻辑放到数据库初始化或对应模块迁移函数。
- 保持向后兼容,避免破坏已有 `data/conversations.db`
- 添加针对迁移和核心查询的单测。
## 新增工具
命令工具优先通过 `tools/*.yaml` 增加,不必改 Go 代码。需要 Go 内置工具时:
- 在合适模块注册 MCP Tool。
- 定义清晰 `InputSchema`
- 处理超时、错误、审计和 HITL 上下文。
- 避免把高风险操作默认免审批。
工具 YAML 规则见 `tools/README.md`
## 新增角色
角色通过 `roles/*.yaml` 管理。常见字段包括名称、描述、系统提示词和工具列表。角色应遵循最小工具集原则,不要把所有工具默认交给专用角色。
## 新增子代理
多代理子 Agent 放在 `agents/*.md`。Front matter 示例:
```yaml
---
name: Vulnerability Triage
id: vulnerability-triage
description: 对漏洞线索进行验证、定级和修复建议整理
tools:
- nmap
- nuclei
bind_role: 综合漏洞扫描
max_iterations: 200
---
```
正文是系统提示词。主代理可使用固定文件名或 `kind: orchestrator`
## 新增 Skill
Skill 放在 `skills/<name>/SKILL.md`。用于提供专题能力、流程说明或附属资料。详见 [Skills 指南](skills-guide.md)。
## 前端开发
前端代码按功能拆分在 `web/static/js/`。新增页面或模块时:
- 复用现有 `apiFetch`、modal、通知、i18n 工具。
- 同步更新 `web/static/i18n/zh-CN.json``en-US.json`
- 避免把敏感 Key 放到前端。
- 高风险按钮要有确认和清晰状态反馈。
i18n 规范见 [前端国际化方案](frontend-i18n.md)。
## OpenAPI
`internal/handler/openapi.go` 维护内置 OpenAPI 输出。新增公开接口后建议同步补:
- path
- method
- summary/description
- requestBody
- responses
- security
这样 `/api-docs` 才能反映最新接口。
## 开发习惯
- 优先保持现有模块边界。
- 大模型、外部 API、文件系统、Shell 相关改动必须考虑超时和错误路径。
- 高风险能力要接入 HITL 或至少有清晰审计。
- 代码变更后运行相关包单测。
## 新增业务模块的完整配方
不要只加一个 Handler。完整模块通常要考虑:
1. 数据模型:是否需要 SQLite 表和迁移。
2. Handler:HTTP 参数、错误码、分页、过滤。
3. Audit:管理动作是否要审计。
4. Monitor:如果会执行长任务,是否要记录执行状态。
5. MCP:是否要暴露给 Agent。
6. HITL:MCP 工具是否有审批边界。
7. OpenAPI:是否更新 `/api/openapi/spec`
8. Frontend:是否需要 i18n、状态、空态、错误提示。
9. Tests:数据库、handler、边界条件。
10. Docs:配置、使用、排错和安全影响。
少做其中一项,后面通常会以“用户看不懂”“Agent 调错”“接口没人会用”的形式返工。
## Handler 错误设计
建议错误响应保持:
```json
{
"error": "machine_readable_code",
"message": "给用户看的说明"
}
```
不要只返回 Go error 字符串。前端需要稳定字段,用户需要可操作建议,日志需要详细错误。
## 长任务设计
扫描、索引、批量任务、C2 等都可能长时间运行。设计时要回答:
- 是否能取消?
- 是否能查询进度?
- 失败后能否重试?
- 结果写在哪里?
- 页面刷新后状态是否还在?
- 是否会阻塞 HTTP 请求?
如果答案是否定的,应考虑接入任务表、事件流或监控模块。
## 测试优先级
最值得补测试的地方:
- 配置热应用。
- HITL 审批分支。
- Shell 超时和无输出。
- 外部 MCP 失败恢复。
- 知识库索引和检索后处理。
- WebShell 编码和系统识别。
- SQLite 迁移兼容。
这些地方比普通 getter/setter 更容易出现真实用户故障。
+122
View File
@@ -0,0 +1,122 @@
# 人机协同(HITL)最佳实践
[English](../en-US/hitl-best-practices.md)
人机协同用于在 Agent 执行工具前做审批拦截。它适合控制高风险操作、保留审计痕迹,并在人工审计压力过大时让审计 Agent 接管常规审批。
## 配置入口
Web 端进入 **系统设置 → 人机协同**,可配置:
- 全局默认审批方:`human``audit_agent`
- 审计 Agent 专用模型:`hitl.audit_model`
- 已决策审计日志保留天数
- 免审批工具白名单:`hitl.tool_whitelist`
- 审批模式与审查编辑模式的审计提示词
对应的 `config.yaml` 示例:
```yaml
hitl:
default_reviewer: human
audit_model:
provider: ""
base_url: ""
api_key: ""
model: "" # 可填小模型;留空复用 openai.model
retention_days: 90
tool_whitelist: [read_file, list_dir, glob, grep, tool_search]
```
`audit_model` 的字段可以只填一部分。空字段会自动继承主 `openai` 配置,因此常见做法是只填 `model`,让审计 Agent 使用更便宜的小模型。
## 推荐审批策略
### 1. 默认人工,逐步放权
刚开始建议:
- `default_reviewer: human`
- 仅把明显只读工具加入 `tool_whitelist`
- 对写文件、执行命令、C2 任务、WebShell 操作保持人工审批
运行一段时间后,观察审计日志,把重复、低风险、误报少的工具加入白名单。
### 2. 人工审不过来时,用小模型接管常规审批
当待审批积压明显时,可以切换为:
```yaml
hitl:
default_reviewer: audit_agent
audit_model:
model: "your-small-reviewer-model"
```
建议让小模型处理:
- 只读查询
- 信息收集
- 端口与服务扫描
- 目录枚举
- 无破坏性的验证命令
仍建议人工处理:
- 删除、覆盖、清空数据
- 修改权限、密码、账号
- 持久化、横向移动、C2 高风险任务
- 对生产目标的写入操作
### 3. 用提示词定义组织策略
审计 Agent 的提示词应该写成策略,而不是泛泛地说“谨慎审批”。建议明确:
- 默认放行哪些低风险操作
- 必须拒绝哪些破坏性操作
- 哪些情况需要人工升级
- 审查编辑模式下允许怎样收窄参数
示例策略片段:
```text
常规信息收集、只读查询、端口扫描默认 approve。
涉及删除文件、清空数据库、修改账号权限、写入持久化后门、停止关键服务时必须 reject。
若目标范围超出用户授权范围,应 reject。
审查编辑模式下,可将路径、目标、命令参数收窄后 approve,但不得扩大攻击面。
```
### 4. 白名单只放稳定低风险工具
白名单工具会跳过审批,因此要保守维护。推荐放:
- `read_file`
- `list_dir`
- `glob`
- `grep`
- `tool_search`
不建议直接全局白名单:
- 任意 shell 执行工具
- 文件写入/删除工具
- C2 任务工具
- WebShell 命令执行工具
## 模式选择
| 模式 | 适用场景 |
|------|----------|
| 关闭 | 本地实验、完全信任工具链 |
| 审批模式 | 只需要通过/拒绝 |
| 审查编辑 | 希望审计 Agent 收窄参数后放行 |
如果你已经配置了小模型审计,推荐从 **审批模式** 开始。只有当你希望 AI 自动收窄路径、目标范围或命令参数时,再开启 **审查编辑**
## 运维建议
- 定期查看 **人机协同 → 审计日志**,调整白名单和提示词。
- 高风险环境下保持 `default_reviewer: human`,只让审计 Agent 辅助给出建议。
- 小模型审批失败时默认保守拒绝,这是预期行为。
- 修改 `hitl.audit_model` 后先在页面点击 **测试审计模型**
- 对生产、客户、真实业务系统操作前,应保留人工最终确认。
+272
View File
@@ -0,0 +1,272 @@
# 知识库
知识库用于把本地安全知识、漏洞手册、测试方法和组织经验转成可检索上下文,供 Agent 在任务中按需引用。
## 启用
```yaml
knowledge:
enabled: true
base_path: knowledge_base
embedding:
provider: openai
model: text-embedding-v4
base_url: ""
api_key: ""
database:
knowledge_db_path: data/knowledge.db
```
`embedding.base_url/api_key` 留空时会复用 `openai` 配置。建议知识库数据库独立保存,便于迁移和复用。
## 内容目录
默认目录是 `knowledge_base/`。项目中已有示例:
```text
knowledge_base/
SQL Injection/
README.md
MySQL Injection.md
Prompt Injection/
README.md
```
推荐用一级目录表示风险类型或知识域,如:
- `SQL Injection`
- `XSS`
- `File Upload`
- `Cloud Security`
- `Incident Response`
## 管理流程
常见流程:
1. 把 Markdown 知识文件放到 `knowledge_base/`
2. 在 Web 知识库页面扫描目录。
3. 重建索引。
4. 用搜索功能验证召回效果。
5. 在角色或任务中要求 Agent 优先查询知识库。
接口入口包括:
- `GET /api/knowledge/categories`
- `GET /api/knowledge/items`
- `POST /api/knowledge/scan`
- `POST /api/knowledge/index`
- `POST /api/knowledge/search`
- `GET /api/knowledge/index-status`
- `GET /api/knowledge/retrieval-logs`
## 索引
索引配置:
```yaml
knowledge:
indexing:
chunk_size: 512
chunk_overlap: 50
max_chunks_per_item: 0
max_rpm: 0
rate_limit_delay_ms: 300
max_retries: 3
retry_delay_ms: 1000
chunk_strategy: markdown_then_recursive
request_timeout_seconds: 120
prefer_source_file: false
batch_size: 10
sub_indexes: []
```
建议:
- 文档结构清晰时用 `markdown_then_recursive`
- 嵌入接口限制严格时降低 `batch_size`,增加 `rate_limit_delay_ms`
- 单篇超长文档可设置 `max_chunks_per_item` 控制成本。
- 需要按业务域隔离时使用 `sub_indexes``sub_index_filter`
## 检索
```yaml
knowledge:
retrieval:
top_k: 5
similarity_threshold: 0.4
multi_query:
max_queries: 4
post_retrieve:
prefetch_top_k: 20
max_context_chars: 0
max_context_tokens: 0
```
检索链路大致为:
1. 用户查询或 Agent 查询。
2. MultiQuery 改写出多个语义变体。
3. 向量检索获取候选块。
4. rerank 精排。
5. 后处理去重、限长。
6. 返回给 Agent 或 API 调用方。
`similarity_threshold` 太高会漏召回,太低会带入噪声。初始建议 0.35 到 0.45。
## Rerank
```yaml
knowledge:
retrieval:
rerank:
provider: ""
model: ""
base_url: ""
api_key: ""
```
留空时会根据 `base_url` 推断。DashScope 常用 `gte-rerank`;其他 OpenAI 兼容端点可能走 `/v1/rerank`。如果服务商不支持 rerank,检索质量可能下降,建议降低 `top_k` 并提高知识条目质量。
## MCP 工具
启用知识库后,会注册类似以下能力:
- 列出风险类型。
- 搜索知识库。
- 获取相关知识片段。
角色提示词中可以写明:
```text
遇到漏洞验证、修复建议或检测方法不确定时,先检索知识库,再给出结论。
```
## 内容编写建议
每篇知识建议包含:
- 适用场景。
- 检测方法。
- 验证步骤。
- 常见误报。
- 修复建议。
- 工具命令示例。
- 参考链接或内部标准。
避免把无关主题堆在同一篇长文中。小而清晰的文档更利于 chunk 和召回。
## 排错
索引失败:
- 检查 embedding API Key、模型名、base_url。
- 降低 `batch_size`
- 增大 `request_timeout_seconds`
- 查看服务日志中的 400/401/429/5xx。
检索为空:
- 检查是否已重建索引。
- 降低 `similarity_threshold`
- 查看 `categories` 是否识别到风险类型。
- 搜索时不要使用过窄的 `riskType`
召回不准:
- 优化标题层级。
- 把混杂内容拆成多篇。
- 增加关键术语和同义词。
- 调整 `top_k``prefetch_top_k` 和 rerank 配置。
## 内部数据流
知识库链路不是“全文搜索”,而是一个多阶段检索系统:
```mermaid
flowchart LR
F["Markdown / Web 知识项"] --> M["Manager"]
M --> C["Chunker"]
C --> E["Embedding"]
E --> V["SQLite Vector Index"]
Q["Agent 查询"] --> MQ["MultiQuery 改写"]
MQ --> V
V --> R["Rerank"]
R --> P["Post-process 去重/限长"]
P --> A["Agent 上下文"]
```
因此检索质量取决于四件事:原文结构、chunk 粒度、embedding 质量、rerank 可用性。单纯调 `top_k` 往往不是最有效的办法。
## 知识项写作反例
不好的知识:
```text
SQL注入很危险,可以用sqlmap扫,修复就是过滤。
```
好的知识:
```markdown
# MySQL UNION 注入验证
## 触发条件
- 参数进入 SELECT 查询并直接拼接。
- 页面返回字段数量错误或类型错误。
## 验证步骤
1. 使用 `' order by 1-- -` 递增列数。
2. 使用 `union select null,...` 校验回显位。
3. 用只读函数确认数据库类型,例如 `database()`
## 误报排除
- WAF 注入拦截页可能模拟 SQL 错误。
- 统一错误页不能直接证明注入。
## 修复
- 参数化查询。
- 最小数据库权限。
- 统一错误处理但不吞掉安全日志。
```
第二种写法能给 chunk 足够的标题、术语和步骤信号,Agent 也能直接执行。
## 调参方法
先固定一组测试问题,例如:
```text
MySQL union 注入怎么判断字段数?
SSRF 如何验证云元数据访问?
文件上传黑名单绕过有哪些误报?
```
然后逐项调:
1. 搜索为空:降低 `similarity_threshold`,确认索引完成。
2. 结果主题错:提高文档标题质量,增加风险类型过滤。
3. 结果片段断裂:增大 `chunk_overlap` 或降低 `chunk_size` 后重建索引。
4. 噪声多:提高 `similarity_threshold`,启用/修复 rerank。
5. 成本高:降低 `multi_query.max_queries``prefetch_top_k``top_k`
每次只改一个参数,并记录查询结果,否则无法判断哪个变量有效。
## 检索日志怎么用
检索日志不只是排错用,还可以反向改进知识库:
- 高频无结果查询:说明缺知识或同义词不足。
- 高频低分查询:说明文档标题和术语不匹配。
- 同一问题召回多个重复文档:说明需要合并或加 category。
- Agent 常忽略知识库结果:说明结果太长、太散或缺明确结论。
## 源码锚点
- 知识管理:`internal/knowledge/manager.go`
- 索引流水线:`internal/knowledge/index_pipeline.go`
- Eino chunk`internal/knowledge/chunk_eino.go`
- 检索器:`internal/knowledge/retriever.go`
- Eino 检索链:`internal/knowledge/eino_retrieve_chain.go`
- rerank`internal/knowledge/rerank_http.go`
- MCP 工具:`internal/knowledge/tool.go`
+189
View File
@@ -0,0 +1,189 @@
# MCP 联邦
CyberStrikeAI 同时支持内置 MCP 工具、独立 HTTP MCP 服务和外部 MCP 联邦。MCP 是 Agent 调用工具的主要协议层。
## 内置 MCP
Web 服务内部会创建 MCP Server,并注册:
- YAML 命令工具。
- 内置安全执行工具。
- 知识库工具。
- 项目事实工具。
- C2 工具。
- WebShell 工具。
- 批量任务工具。
- 视觉分析工具。
前端和 Agent 通常通过应用内部调用,不需要额外配置。
## HTTP MCP 服务
配置:
```yaml
mcp:
enabled: true
host: 0.0.0.0
port: 8081
auth_header: "X-MCP-Token"
auth_header_value: "random-secret"
```
生产环境必须设置 `auth_header_value`,并限制网络访问。
## Web 内 MCP 端点
登录后可通过:
```text
POST /api/mcp
```
该端点复用 Web 认证,适合内部页面或受控集成。
## 外部 MCP
外部 MCP 配置在:
```yaml
external_mcp:
servers: {}
```
也可以通过 Web 的 MCP 管理页面新增、启动、停止和删除。
接口:
- `GET /api/external-mcp`
- `GET /api/external-mcp/stats`
- `GET /api/external-mcp/:name`
- `PUT /api/external-mcp/:name`
- `POST /api/external-mcp/:name/start`
- `POST /api/external-mcp/:name/stop`
- `DELETE /api/external-mcp/:name`
## stdio
stdio MCP 适合本机命令启动的工具服务。
关注点:
- 命令路径必须存在。
- 工作目录正确。
- 环境变量完整。
- 进程退出会导致工具不可用。
- 日志中查看启动失败原因。
## HTTP / SSE
HTTP 或 SSE MCP 适合远端或长期运行服务。
关注点:
- URL 可达。
- 认证头正确。
- TLS 证书可信。
- 代理和防火墙放行。
- 服务端协议版本兼容。
## 工具暴露策略
工具过多会增加上下文成本和误选概率。多代理中可通过:
```yaml
multi_agent:
eino_middleware:
tool_search_enable: true
tool_search_min_tools: 20
tool_search_always_visible: 12
tool_search_always_visible_tools:
- read_file
- glob
- grep
- tool_search
```
让常用工具常驻,其余工具由 `tool_search` 动态解锁。
## 安全建议
- 外部 MCP 只接入可信服务。
- 远端 MCP 必须认证。
- 高风险工具不要常驻上下文。
- 外部 MCP 的文件系统和命令执行能力要单独评估。
- 变更外部 MCP 后查看审计日志。
## 调试
排查顺序:
1. `/api/external-mcp/stats` 查看状态。
2. 检查服务日志。
3. 单独运行 stdio 命令。
4. 用 curl 测试 HTTP/SSE 地址。
5. 检查工具是否被角色或 tool_search 策略隐藏。
## MCP 生命周期
外部 MCP 的生命周期不是简单的“添加 URL”:
1. 注册配置:名称、类型、命令或 URL、环境变量。
2. 启动连接:stdio 拉起进程,HTTP/SSE 建立客户端。
3. 拉取工具列表:工具名、描述、schema 进入平台。
4. 暴露给 Agent:受角色、tool_search、HITL 影响。
5. 执行工具:参数校验、调用、记录监控。
6. 连接恢复:进程退出或网络失败后尝试恢复。
7. 停止/删除:从运行时和配置中移除。
排错时要确认卡在哪一步。
## 工具命名规范
工具名应:
- 稳定。
- 小写或 snake_case。
- 表达动作和对象。
- 避免和内置工具重名。
不建议:
```text
run
execute
scan
tool1
```
建议:
```text
burp_send_to_repeater
asset_lookup_domain
cloud_list_public_buckets
```
好的工具名会提升 tool_search 命中率,也降低误调用。
## 外部 MCP 安全审查清单
接入前问:
- 它能读写本机文件吗?
- 它能执行命令吗?
- 它会访问哪些网络?
- 它是否把请求发给第三方?
- 它的工具描述是否可信?
- 它的输出是否可能包含 prompt injection
- 它是否需要独立运行用户或容器隔离?
只要答案不清楚,就不要放进生产环境常驻工具池。
## 源码锚点
- 外部 MCP Manager`internal/mcp/external_manager.go`
- 连接恢复:`internal/mcp/connection_recovery.go`
- MCP 工具适配:`internal/einomcp/mcp_tools.go`
- 外部 MCP Handler`internal/handler/external_mcp.go`
- 工具调用通知:`internal/einomcp/tool_invoke_notify.go`
+216
View File
@@ -0,0 +1,216 @@
# 插件开发
CyberStrikeAI 当前仓库中的插件主要位于 `plugins/`,已有 **Burp Suite 扩展**与 **Chromium 浏览器扩展** 两个参考实现。插件通常通过 HTTP API、MCP 或本地文件与主应用集成。
## 目录
```text
plugins/
README.md
burp-suite/
cyberstrikeai-burp-extension/
src/main/java/burp/
README.md
README.zh-CN.md
build.gradle
pom.xml
browser-extension/
cyberstrikeai-browser-extension/
manifest.json
devtools.js
background/service-worker.js
panel/
popup/
lib/
README.md
README.zh-CN.md
package.sh
```
## 插件类型
常见集成方式:
- 浏览器或安全工具扩展:调用 CyberStrikeAI API。
- MCP Server:向 CyberStrikeAI 暴露新工具。
- 文件型扩展:提供 tools、roles、skills、agents。
- Webhook/机器人:通过平台回调与 CyberStrikeAI 对话。
## Burp Suite 扩展
Burp 插件目录包含 Java 源码和构建脚本。典型能力:
- 读取 Burp 中的 HTTP 请求/响应。
- 格式化消息。
- 调用 CyberStrikeAI API。
- 在 Burp 标签页展示 AI 分析结果。
构建前确认:
- JDK 可用。
- Gradle 或 Maven 可用。
- CyberStrikeAI 服务地址和认证配置正确。
## 浏览器扩展(Chromium DevTools
浏览器扩展目录为 MV3 DevTools 扩展,与 Burp 插件能力对齐:捕获 HTTP 流量 → 格式化 Prompt → SSE 流式输出 AI 结果。完整安装与 UI 说明见 `plugins/browser-extension/cyberstrikeai-browser-extension/README.zh-CN.md`
典型能力:
- 在 DevTools **Network** 中捕获 XHR/Fetch(可暂停)。
- 原始 HAR 存内存;展示与 AI Prompt 归一化为 **HTTP/1.1**(与 Burp 一致)。
- 调用 CyberStrikeAI 登录、Validate、Agent Stream API。
- DevTools 面板展示 Progress / FinalPopup 只读连接状态。
构建与加载:
- 无需编译:`chrome://extensions/` → 加载已解压 → 选择 `cyberstrikeai-browser-extension/`
- 打包:`bash package.sh``dist/cyberstrikeai-browser-extension.zip`
### 浏览器插件认证最佳实践
服务端 `POST /api/auth/login` 返回 `{ token, expires_at }`**无 refresh token**,插件不应假设 Token 会自动续期。参考实现见 `lib/auth-session.js``lib/api.js``panel/panel.js`
| 实践 | 说明 |
| --- | --- |
| Session 存储 | Token 与 `expires_at``chrome.storage.session`(关浏览器失效),Password 不落盘 |
| 剩余时间 | 状态栏显示 `OK · 剩余 11h 30m`;剩余 <30min 警告 |
| 本地检测 | 每 30s 检查 `expires_at` 并调用 `GET /api/auth/validate` |
| 服务端探测 | 切回 DevTools 面板 / 窗口聚焦时立即探测 |
| 服务不可达 | 显示「无法连接服务」,不清 Token(便于服务重启中) |
| 401/403 | 清空 Token、展开连接栏(服务重启后 session 内存清空) |
| Send 前校验 | 调用 `ensureAuthReady()`,避免过期 Token 发起 SSE |
| 按需授权 | `optional_host_permissions`Validate 时请求目标 origin |
扩展重载后 DevTools 面板上下文可能失效:需 **关闭 DevTools → 重载扩展 → 再开 F12**
### 浏览器插件数据与性能边界
插件侧应设内存上限,避免 DevTools 长时间开启拖垮浏览器:
- 捕获:200 条 / Tab20 个 Tab 槽;Progress 512KB / run。
- 默认 **XHR/Fetch only** + 静态资源预过滤;不需要捕获时用 **已暂停**
- 大响应走截断或摘要后再进 Prompt,不要整包塞进消息。
## API 对接建议
插件调用主应用时:
-`POST /api/auth/login`,再 `GET /api/auth/validate` 确认会话。
- 保存 `expires_at`,过期后重新登录(无 silent refresh)。
- 优先调用 `/api/eino-agent/stream``/api/multi-agent/stream`SSE)。
- 大文件通过 `/api/chat-uploads` 上传,再在消息中引用。
- 查询结果或漏洞可写入 `/api/vulnerabilities`
- 项目信息可写入 `/api/projects/:id/facts`
完整接口以 `/api-docs` 为准。
## MCP 插件
如果插件的目标是给 Agent 增加工具,优先实现 MCP Server。然后在外部 MCP 管理中接入:
- stdio:本机启动。
- HTTP/SSE:长期服务。
MCP 工具设计建议:
- schema 明确。
- 参数最小化。
- 输出结构稳定。
- 错误信息可读。
- 高风险动作拆成独立工具,方便 HITL 审批。
## 文件型扩展
插件也可以交付:
- `tools/*.yaml`
- `roles/*.yaml`
- `skills/<name>/SKILL.md`
- `agents/*.md`
这种方式简单可靠,适合内部方法论或工具链沉淀。
## 发布检查
发布插件前确认:
- 不包含 API Key、Cookie、目标信息。
- README 有安装、配置、卸载说明。
- 错误提示清晰。
- 与当前 CyberStrikeAI API 版本兼容。
- 高风险能力有明显说明。
## 版本兼容
插件应避免依赖未公开的前端内部实现。优先依赖:
- `/api/openapi/spec`
- 稳定 HTTP API。
- MCP 协议。
- 文件目录规范。
如果必须依赖内部接口,插件 README 中应标注兼容版本。
## 插件设计的三个层次
| 层次 | 例子 | 优点 | 代价 |
| --- | --- | --- | --- |
| API 插件 | Burp / 浏览器扩展调用 Agent Stream | 易实现,适合 UI 集成 | 依赖认证和 API 稳定性 |
| MCP 插件 | 提供新工具给 Agent | Agent 可主动调用 | 需要 schema 和安全设计 |
| 资源包插件 | 交付 tools/roles/skills/agents | 最简单,可版本化 | 交互能力弱 |
插件一开始不必做成 MCP。如果只是“把 Burp / 浏览器里的 HTTP 请求交给 AI 分析”,API 插件更直接;如果要让 Agent 主动调用 Burp 扫描或查询结果,再做 MCP。
## API 插件请求设计
发送给 Agent 的内容应包含:
- 来源工具和上下文。
- 目标 URL、方法、关键 header。
- 请求体和响应体的截断策略。
- 用户希望 AI 做什么。
- 授权边界。
不要把完整大响应直接塞进消息。大文件应走上传接口或做摘要。
## MCP 插件 schema 设计
坏 schema
```json
{"cmd":{"type":"string"}}
```
好 schema
```json
{
"target_url": {"type":"string","description":"授权目标 URL"},
"scan_profile": {"type":"string","enum":["passive","active-safe"]},
"max_requests": {"type":"integer","description":"最大请求数"}
}
```
schema 越具体,HITL 越容易判断风险,Agent 也越不容易发散。
## 插件安全边界
插件不要绕过平台安全控制:
- 不要直接执行本机高风险命令而不暴露给 HITL。
- 不要在插件内保存明文长期凭证(Password 仅用于登录,Token 用 session 存储)。
- 不要默认把目标数据发给第三方服务。
- 不要依赖浏览器本地状态绕过登录。
- 收到 401/403 应清空会话并提示重新认证,不要静默重试或忽略。
## 源码锚点
- Burp 插件 Java 代码:`plugins/burp-suite/cyberstrikeai-burp-extension/src/main/java/burp/`
- 浏览器扩展:`plugins/browser-extension/cyberstrikeai-browser-extension/`
- 认证:`lib/auth-session.js``lib/api.js``lib/storage.js`
- 主 UI`panel/panel.js`
- 捕获:`devtools.js``background/service-worker.js`
- OpenAPI`internal/handler/openapi.go`
- 外部 MCP`internal/handler/external_mcp.go`
- Web 端认证参考:`web/static/js/auth.js`
+169
View File
@@ -0,0 +1,169 @@
# 发布流程
本文用于维护者或部署者发布、升级和回滚 CyberStrikeAI。
## 版本准备
发布前检查:
- `README.md``README_CN.md` 的功能说明是否更新。
- `docs/` 是否补充新功能文档。
- `config.yaml` 示例是否包含新增配置。
- OpenAPI 是否包含新增接口。
- 中英文 i18n 是否同步。
- 高风险功能是否有安全说明。
## 测试
至少运行:
```bash
go test ./internal/...
```
如果修改了入口、构建或命令:
```bash
go test ./cmd/...
go build -o cyberstrike-ai ./cmd/server
```
如果修改前端,手动验证:
- 登录。
- 对话流式输出。
- 设置保存和应用。
- 工具列表。
- 相关页面无控制台错误。
## 构建
```bash
go build -o cyberstrike-ai ./cmd/server
```
发布包应包含:
- `cyberstrike-ai`
- `web/templates/`
- `web/static/`
- `config.yaml` 示例。
- `tools/`
- `roles/`
- `skills/`
- `agents/`
- `docs/`
- `README.md` / `README_CN.md`
- `LICENSE`
不要把本地 `data/`、真实 `config.yaml` 密钥、上传附件和日志打进公开发布包。
## 升级检查清单
升级前:
- 停服务。
- 备份 `config.yaml`
- 备份 `data/`
- 备份自定义 `tools/roles/skills/agents/knowledge_base`
- 记录当前版本和启动方式。
升级后:
- 启动服务。
- 登录。
- 测试模型。
- 检查工具列表。
- 检查知识库状态。
- 检查外部 MCP。
- 检查 C2/WebShell 是否按预期启用或关闭。
- 查看日志和审计。
## 回滚
触发回滚的常见情况:
- 服务无法启动。
- 数据库迁移失败。
- 核心对话功能不可用。
- 高风险功能行为异常。
回滚步骤:
1. 停止新版本。
2. 恢复旧二进制或旧代码。
3. 恢复升级前 `config.yaml`
4. 恢复升级前 `data/`
5. 启动旧版本并验证。
如果新版已修改数据库结构,必须恢复数据库备份,不能只替换二进制。
## Changelog 建议
每个版本记录:
- 新增功能。
- 行为变更。
- 配置变更。
- 数据库变更。
- 安全修复。
- 兼容性说明。
- 升级注意事项。
高风险模块的变更要单独标出,例如 C2、WebShell、终端、外部 MCP、HITL。
## 发布风险分级
| 改动 | 风险 | 必测 |
| --- | --- | --- |
| 文档、图片 | 低 | 链接和渲染 |
| 前端页面 | 中 | 登录、页面状态、API 错误 |
| Handler/API | 中 | OpenAPI、权限、错误码 |
| 配置结构 | 高 | 旧配置兼容、ApplyConfig |
| 数据库结构 | 高 | 旧库迁移、回滚策略 |
| Agent/MCP/HITL | 高 | 工具调用、审批、流式中断 |
| C2/WebShell/Terminal | 极高 | 授权环境、审计、禁用开关 |
发布说明里要按风险级别提示用户,而不是只列功能点。
## 配置兼容策略
新增配置字段要遵循:
- 省略时有安全默认值。
- 旧配置能启动。
- 示例 `config.yaml` 有注释。
- Web 设置页不会把未知字段误删。
- 热应用和重启两种路径都验证。
如果新增字段默认开启高风险功能,应重新考虑默认值。
## 数据库变更策略
SQLite 迁移要考虑:
- 用户可能从很老版本直接升级。
- 迁移中断后再次启动是否幂等。
- 新字段是否允许空值。
- 索引是否会锁表太久。
- 是否需要数据回填。
发布说明必须写清楚“升级前备份 data/”。
## Release 验收脚本思路
最小自动化:
```bash
go test ./internal/...
go test ./cmd/...
go build -o cyberstrike-ai ./cmd/server
```
手动冒烟:
```text
登录 -> 模型测试 -> 新建对话 -> 工具列表 -> HITL -> 知识库 -> 外部 MCP -> 关闭/开启 C2
```
对高风险模块,宁可多做一个授权靶场测试,也不要只靠单测放行。
+1 -1
View File
@@ -1,6 +1,6 @@
# CyberStrikeAI 机器人使用说明
[English](robot_en.md)
[English](../en-US/robot.md)
本文档说明如何通过**个人微信**、**钉钉**、**飞书**与 **企业微信** 与 CyberStrikeAI 对话(长连接 / 回调模式),在手机端即可使用,无需在服务器上打开网页。按下面步骤操作可避免常见弯路。
+223
View File
@@ -0,0 +1,223 @@
# 运维 Runbooks
[English](../en-US/runbooks.md)
Runbook 是“遇到一个真实任务时照着做”的步骤清单。本文覆盖 CyberStrikeAI 最常见的运维和安全测试操作。
## Runbook 1:生产实例从 0 到可用
适用:内网团队或生产红队平台首次部署。
如果只是本地或临时验证,优先用仓库自带脚本启动:
```bash
chmod +x run.sh && ./run.sh
```
确认可用后,再决定是否升级为 systemd + 反向代理的长期部署。
### 前置确认
- 运行主机已纳入资产管理。
- 访问路径确定:内网、VPN、堡垒机或反向代理。
- 有模型 API Key 和允许使用的模型。
- 已决定是否启用 C2、WebShell、外部 MCP。
### 步骤
1. 准备目录:
```bash
mkdir -p /opt/CyberStrikeAI
```
2. 放置二进制和资源目录:
```text
cyberstrike-ai
web/
tools/
roles/
skills/
agents/
docs/
config.yaml
```
3. 修改关键配置:
```yaml
auth:
password: "<long-random-password>"
server:
host: 127.0.0.1
port: 8080
tls_enabled: false
audit:
enabled: true
c2:
enabled: false
```
4. 配置反向代理 HTTPS,并限制来源 IP。
5. 使用 systemd 托管进程。
6. 登录 Web,测试模型。
7. 检查工具列表和审计日志。
8. 建立备份策略。
### 验收
- `/api/auth/validate` 登录后返回成功。
- 模型测试成功。
- `tools/` 能正常加载。
- 审计页面能看到登录事件。
- C2 在不需要时访问返回禁用状态。
### 回滚
恢复:
- 上一版二进制。
- 上一版 `config.yaml`
- 升级前 `data/`
## Runbook 2:接入外部 MCP
适用:接入本地工具服务、Burp 辅助服务、资产查询服务等。
### 前置确认
- MCP 服务可信。
- 明确它是否能读文件、写文件、执行命令或访问第三方网络。
- 确定接入方式:stdio、HTTP、SSE。
### 步骤
1. 在外部 MCP 页面新增服务。
2. 如果是 stdio,填写命令、参数、工作目录和环境变量。
3. 如果是 HTTP/SSE,填写 URL 和认证信息。
4. 启动服务。
5. 查看 `/api/external-mcp/stats`
6. 检查工具列表是否出现。
7. 用低风险参数执行一次工具。
8. 把高风险工具排除在全局免审批白名单之外。
### 验收
- MCP 状态为 running。
- 工具 schema 可见。
- Agent 能通过 `tool_search` 找到工具。
- 工具执行记录出现在监控页。
- 配置变更出现在审计页。
### 回滚
- 停止 MCP。
- 删除外部 MCP 配置。
- 从角色/白名单中移除相关工具。
- 检查 Agent 当前任务是否仍持有旧上下文。
## Runbook 3:启用知识库并调优召回
适用:把内部安全知识、漏洞手册或测试方法接入 Agent。
### 步骤
1. 修改配置:
```yaml
knowledge:
enabled: true
base_path: knowledge_base
embedding:
model: text-embedding-v4
retrieval:
top_k: 5
similarity_threshold: 0.4
```
2. 把 Markdown 放入 `knowledge_base/`
3. 在 Web 知识库页面执行扫描。
4. 重建索引。
5. 准备 5 到 10 个固定测试问题。
6. 搜索并记录命中情况。
7. 根据结果调 `threshold``top_k`、chunk 参数和文档标题。
### 验收
- `index-status` 显示索引完成。
- 常见问题能命中正确文档。
- Agent 在不确定时会先查知识库。
- 检索日志能显示查询和命中文档。
### 常见回滚
- 关闭 `knowledge.enabled`
- 恢复旧的 `data/knowledge.db`
- 降低 `batch_size` 后重新索引。
## Runbook 4:一次授权 Web 测试标准流程
适用:对授权目标做 Web 安全测试。
### 步骤
1. 创建项目,记录授权范围。
2. 新建对话,绑定项目。
3. 选择最小角色,例如“信息收集”或“Web 应用扫描”。
4. 明确目标、时间窗口、禁止动作。
5. 先执行只读信息收集。
6. 发现线索后写入项目事实。
7. 对高风险验证请求使用 HITL。
8. 确认漏洞后写入漏洞管理。
9. 生成攻击链或报告材料。
10. 清理上传文件、临时 workspace 和无用执行记录。
### 验收
- 每个漏洞都有证据、影响、复现和修复建议。
- 高风险操作有 HITL 记录。
- 项目事实能复现测试路径。
- 报告不包含无关敏感数据。
## Runbook 5C2 演练结束清理
适用:授权演练中启用了 C2。
### 步骤
1. 停止所有 listener。
2. 列出 sessions,确认没有仍在线的授权会话。
3. 导出必要 task 结果。
4. 删除 payload 或移动到受控归档。
5. 删除无用 task、event、file。
6. 审计 C2 操作记录。
7. 将关键结果写入项目事实或报告。
8.`c2.enabled` 改回 false,除非平台持续需要。
### 验收
- 无运行中 listener。
- 无待处理 task。
- payload 不再公开可下载。
- 审计与报告能解释整个生命周期。
## Runbook 6Agent 不调用工具
排查顺序:
1. 当前角色是否绑定了该工具。
2. 工具是否在 `/api/config/tools` 中出现。
3. `tool_search` 是否隐藏了该工具。
4. 工具描述是否过短或命名不清。
5. HITL 是否挂起。
6. Agent 是否处于总结/结束阶段。
7. 多代理子 Agent 是否有自己的工具限制。
修复方式:
- 把工具加入角色。
- 优化 `short_description`
- 加入 `tool_search_always_visible_tools`
- 在提示词中明确什么时候使用。
- 检查过程详情和监控记录。
+140
View File
@@ -0,0 +1,140 @@
# 安全加固指南
[English](../en-US/security-hardening.md)
本文给出 CyberStrikeAI 上线前和持续运行中的安全加固清单。
## 上线前必做
- 修改 `auth.password` 为长随机密码。
- 使用 HTTPS,或放在可信反向代理之后。
- 限制来源 IP、VPN 或堡垒机访问。
- 开启 `audit.enabled`
- 不需要 C2 时设置 `c2.enabled: false`
- 不暴露独立 HTTP MCP,除非设置强认证和网络隔离。
- 外部 MCP 只接可信服务。
- 备份 `config.yaml``data/`、自定义资源目录。
## 反向代理建议
Nginx 基线:
```nginx
client_max_body_size 200m;
proxy_buffering off;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
```
建议额外加:
```nginx
add_header X-Content-Type-Options nosniff;
add_header Referrer-Policy no-referrer;
add_header X-Frame-Options DENY;
```
## HITL 白名单基线
推荐最小白名单:
```yaml
hitl:
tool_whitelist:
- read_file
- glob
- grep
- tool_search
```
不要默认加入:
- `execute`
- WebShell 写入/执行工具
- C2 任务和 payload 工具
- 外部 MCP 高风险工具
- 删除、写入、上传、持久化相关工具
## 文件权限
建议:
```bash
chmod 600 config.yaml
chmod 700 data
```
生产环境使用独立系统用户运行:
```text
cyberstrike-ai:cyberstrike-ai
```
避免 root 运行,除非明确需要绑定低端口或访问特殊资源。
## 外部 MCP 审查
接入前确认:
- 工具是否能执行命令。
- 是否能读写本机文件。
- 是否会把数据发往第三方。
- 是否有自己的认证。
- 是否会返回不可信网页或模型内容。
- 是否需要容器隔离。
接入后:
- 高风险工具不进白名单。
- 定期检查工具列表变化。
- 审计配置变更。
## C2 和 WebShell
C2
- 默认关闭。
- 演练窗口临时开启。
- Listener 端口与管理端口分离。
- 结束后清理 payload、session、task、event。
WebShell
- 只保存授权目标。
- 使用清晰命名。
- 写入/删除/执行必须审批。
- 项目结束删除连接。
## 数据保留
建议:
- 审计:30-90 天。
- 工具监控:90-180 天。
- 上传附件:项目结束清理。
- C2/WebShell 输出:只保留报告需要的证据。
- 知识库:不放真实凭证和客户私密数据。
## 周期巡检
每周:
- 登录失败和异常 IP。
- 配置变更。
- 外部 MCP 增删改。
- 长时间运行工具。
- C2 是否被意外开启。
- WebShell 连接是否过期。
- 磁盘空间和数据库大小。
每个项目结束:
- 清理临时 workspace。
- 删除无用附件。
- 归档必要证据。
- 删除过期 WebShell/C2 资源。
- 导出审计记录。
+180
View File
@@ -0,0 +1,180 @@
# 安全模型
CyberStrikeAI 面向授权安全测试场景,内置命令执行、MCP 工具、WebShell、C2、批量任务和多代理编排等能力。部署者必须把它当作高权限安全工具管理,而不是普通聊天应用。
## 信任边界
主要边界:
- Web 登录用户:可以发起对话、调用工具、修改配置、管理 WebShell/C2/知识库。
- Agent:根据角色、工具列表、HITL 策略调用内置或外部工具。
- MCP 工具:可能访问本机文件、执行命令、调用外部服务或操作目标系统。
- 外部 MCP:由第三方进程或远端服务提供,需单独信任。
- 机器人入口:企业微信、钉钉、飞书等回调入口不走 Web 登录,但有平台验签和速率限制。
如果一个账号可以登录 Web,就应视为拥有该 CyberStrikeAI 实例的操作权限。
## 认证与会话
`auth.password` 是 Web 登录密码。建议:
- 首次部署立即修改默认密码。
- 使用长随机密码,并限制分享范围。
- 将服务放在内网、VPN、堡垒机或反向代理认证后面。
- 生产环境开启 HTTPS,避免明文传输 Cookie。
- 结合反向代理限制来源 IP。
登录态有效期由 `auth.session_duration_hours` 控制。
## 工具执行风险
工具来源包括:
- 内置安全执行工具。
- `tools/` 下的 YAML 命令工具。
- Eino Skills 文件系统工具,如 `read_file``write_file``edit_file``execute`
- 外部 MCP 暴露的工具。
- C2 和 WebShell 相关 MCP 工具。
风险控制建议:
- 只启用当前任务需要的工具。
- 高风险命令工具不要加入全局白名单。
- 给角色绑定最小工具集合。
- 对 destructive、持久化、横向移动、凭证操作保持人工审批。
- 外部 MCP 尽量使用本地可信进程,远端 MCP 必须有认证和网络隔离。
## HITL
HITL 是工具调用前的审批层。常见模式:
- `human`:人工审批。
- `audit_agent`:审计 Agent 自动审批。
- `review_edit`:审计 Agent 可改参后放行。
建议策略:
- 新环境默认人工审批。
- 只把只读、低风险、稳定工具加入白名单。
- 扫描类工具按目标范围配置角色和提示词约束。
- 写入、删除、执行 payload、C2、WebShell、账号改动等操作必须谨慎审批。
详见 [HITL 最佳实践](hitl-best-practices.md)。
## 审计
平台审计由 `audit` 配置控制,记录登录、配置、资源管理等平台操作。它不记录完整对话正文,也不等同于取证日志。
工具执行记录由监控模块维护,保留时间由 `monitor.retention_days` 控制。
建议:
- 开启 `audit.enabled`
- 定期导出审计日志。
- 配置合理保留期。
- 对失败登录、配置变更、C2/WebShell 操作重点复核。
## C2 风险
内置 C2 会启动监听器、生成 payload、接收会话并执行任务。仅在明确授权的靶场、内网演练或红队环境中启用。
建议:
- 不使用时设置 `c2.enabled: false`
- 不在公网暴露 C2 监听端口,除非有明确授权和隔离。
- 对 payload 文件、回连地址、任务输出进行访问控制。
- C2 任务建议走 HITL。
## WebShell 风险
WebShell 管理允许对已登记连接执行命令和文件操作。建议:
- 只添加授权目标。
- 给连接使用清晰名称、标签和备注。
- 不在共享环境保存真实生产 WebShell。
- AI 使用 WebShell 前确认目标和命令。
- 清理失效或不再授权的连接。
## 数据与隐私
本地会保存:
- 对话和消息:`data/conversations.db`
- 知识库索引:`data/knowledge.db`
- WebShell、C2、漏洞、项目、任务等业务数据。
- 上传附件:`chat_uploads/`
建议:
- 限制文件权限。
- 备份加密。
- 不上传无授权的敏感数据。
- 清理不再需要的会话、附件、C2 输出和审计日志。
## 生产基线
最低建议:
- 强密码 + HTTPS + 内网访问。
- `audit.enabled: true`
- `mcp.auth_header_value` 设置随机值。
- 不需要时关闭 `c2.enabled`
- 外部 MCP 最小化启用。
- 高风险工具不进白名单。
- 定期备份和更新。
## 真实威胁模型
| 威胁 | 攻击路径 | 影响 | 防护点 |
| --- | --- | --- | --- |
| Web 密码泄露 | 登录管理面,调用终端/WebShell/C2 | 完整接管平台能力 | 强密码、HTTPS、内网、反向代理认证、审计 |
| Prompt Injection | 目标页面或文档诱导 Agent 调高权限工具 | 越权执行工具或泄露数据 | 角色边界、HITL、工具最小化、知识库来源标注 |
| 外部 MCP 恶意 | MCP 服务返回误导描述或执行副作用 | 本机或目标系统受影响 | 只接入可信 MCP、独立运行用户、网络隔离 |
| 工具 YAML 被篡改 | 改写命令模板或参数 | Agent 调用时执行恶意命令 | 文件权限、代码审查、工具白名单 |
| C2 滥用 | 生成 payload 或下发任务到非授权目标 | 法律和业务风险 | 默认关闭、审批、事件保留、网络隔离 |
| WebShell 误操作 | AI 或用户在生产目标执行破坏命令 | 业务中断或数据损坏 | 连接命名、人工确认、只读优先、删除过期连接 |
| 数据库泄露 | 复制 `data/*.db` 或上传目录 | 对话、目标、漏洞、连接信息泄露 | 文件权限、加密备份、最小保留 |
## 授权边界写法
每个高风险角色都应把授权边界写进提示词,而不是只依赖用户口头说明。示例:
```text
你只能在用户明确给出的目标范围内行动。若需要执行写入、删除、爆破、持久化、凭证访问、C2、WebShell 或横向移动相关操作,必须先说明目的、影响、目标和回滚方式,并等待 HITL 审批。
```
这段话不能代替技术控制,但能降低 Agent 在模糊任务中扩张行为边界的概率。
## HITL 不是万能保险
HITL 的风险在于审批者看到的是“工具名 + 参数 + 上下文摘要”,不是完整现实世界影响。下面几类情况要特别保守:
- 参数看似只读,但工具本身会触发大量请求或写缓存。
- 命令通过 `bash -c`、脚本、base64 包装隐藏真实动作。
- 外部 MCP 工具描述不可信。
- WebShell 目标名称模糊,无法确认是否生产环境。
- C2 payload 生成和分发链路不在平台内。
审计 Agent 适合筛掉普通低风险请求,不适合替代人类批准破坏性动作。
## 数据最小化原则
不要把这些内容长期留在平台里:
- 真实客户凭证。
- 未脱敏报告。
- 生产数据库导出。
- 长期有效 Cookie。
- 无关目标的扫描输出。
- 已结束项目的 WebShell/C2 会话。
建议按项目结束流程清理:附件、WebShell 连接、C2 payload、临时 workspace、长输出工具记录。
## 源码锚点
- 认证会话:`internal/security/auth_manager.go`
- 认证中间件:`internal/security/auth_middleware.go`
- 限流:`internal/security/ratelimit.go`
- Shell 执行:`internal/security/executor.go`
- HITL 执行:`internal/handler/hitl_execution.go`
- 审计服务:`internal/audit/service.go`
+180
View File
@@ -0,0 +1,180 @@
# Skills 指南
Skills 用于给 Agent 提供可按需加载的专题能力、流程说明、模板和参考资料。它适合承载稳定方法论,而不是一次性任务输入。
## 目录结构
默认目录:
```yaml
skills_dir: skills
```
推荐结构:
```text
skills/
api-security-testing/
SKILL.md
ssrf-testing/
SKILL.md
cyberstrike-eino-demo/
SKILL.md
REFERENCE.md
assets/
```
每个 Skill 至少包含 `SKILL.md`
## SKILL.md
`SKILL.md` 使用 YAML front matter
```markdown
---
name: ssrf-testing
description: SSRF 漏洞识别、验证、绕过和修复建议流程
---
# SSRF Testing
当任务涉及服务端请求伪造、URL 回调、云元数据访问或内网探测时使用本技能。
```
`description` 很重要,Agent 会根据它判断何时加载。
## 渐进式披露
Eino Skills 支持按需加载。配置:
```yaml
multi_agent:
eino_skills:
disable: false
filesystem_tools: true
skill_tool_name: skill
```
Agent 初始只看到技能名称和描述,真正需要时再调用 `skill` 读取详情,减少上下文占用。
## 适合写成 Skill 的内容
- 某类漏洞测试流程。
- 安全审计 checklist。
- 报告模板。
- 工具组合方法。
- 内部规范。
- 常见误报判断。
不适合:
- 临时目标信息。
- API Key、密码、Cookie。
- 经常变化的扫描结果。
- 大量无结构原始日志。
## 附属文件
Skill 可以带附属文件,如 `REFERENCE.md`、模板、字典或示例。`SKILL.md` 中应说明何时读取这些文件。
建议:
- 主文件保持短而清晰。
- 参考资料按主题拆分。
- 大文件只在必要时读取。
## 与角色绑定
角色可以提示 Agent 使用某类 Skill;Skill 也可以通过页面管理和角色形成绑定关系。建议:
- 通用技能保持不绑定,按描述自动触发。
- 高风险技能绑定到专用角色。
- 同类技能不要描述过度重叠。
## 开发建议
Skill 内容结构:
1. 触发场景。
2. 目标和边界。
3. 操作步骤。
4. 工具建议。
5. 输出格式。
6. 风险和禁止事项。
7. 参考资料。
写法要让 Agent 能执行,而不是只给人阅读。
## 排错
Skill 没被使用:
- `description` 过窄或过模糊。
- 任务没有触发关键词。
- `multi_agent.eino_skills.disable: true`
- Skill 文件 front matter 格式错误。
Skill 读取太多:
- 拆分附属文件。
-`SKILL.md` 中明确“只有在需要 X 时读取 Y”。
- 删除重复内容。
## Skill 设计深水区
Skill 的核心价值不是“让 Agent 知道一个概念”,而是让 Agent 在正确时机拿到一套可执行的程序。写 Skill 时要特别关注触发条件和退出条件。
推荐结构:
```markdown
## When to use
明确触发场景。
## Preconditions
需要用户提供什么、目标必须满足什么。
## Procedure
按步骤执行,每步说明工具、输入和判断标准。
## Stop conditions
什么情况下停止、升级审批或转人工。
## Output
最终结果格式。
```
## 反模式
| 反模式 | 后果 | 改法 |
| --- | --- | --- |
| 描述过泛:`用于安全测试` | 几乎所有任务都触发 | 写具体漏洞、场景、信号 |
| 内容像百科 | Agent 不知道下一步做什么 | 改成流程和决策树 |
| 把敏感配置写进 Skill | 泄露和误用 | 用运行时配置或用户输入 |
| 一个 Skill 装所有内容 | 读取成本高,召回混乱 | 按漏洞/任务拆分 |
| 没有停止条件 | Agent 可能持续扩大范围 | 写明何时停止和审批 |
## Skill 与知识库的区别
- Skill:指导 Agent 怎么做,强调流程。
- 知识库:提供事实、案例和参考,强调检索。
例如 SSRF
- Skill 写“如何测试 SSRF、如何判定、何时停止”。
- 知识库写“云厂商 metadata 地址、历史绕过、修复方案”。
## 本地文件工具风险
`filesystem_tools: true` 会暴露读写和执行能力。它对开发和自动化很有用,但也是安全边界。生产环境建议:
- 配合 `workspace_root_dir` 限制工作目录。
- 对写入和执行动作使用 HITL。
- 不把 `execute` 加入全局白名单。
- Skill 中明确禁止读写授权范围外文件。
## 源码锚点
- Skill 包校验:`internal/skillpackage/validate.go`
- Skill 服务:`internal/skillpackage/service.go`
- Eino Skills 接入:`internal/multiagent/eino_skills.go`
- Skills Handler`internal/handler/skills.go`
+191
View File
@@ -0,0 +1,191 @@
# 测试指南
CyberStrikeAI 的测试包括 Go 单测、配置验证、API 手测、MCP 工具验证和前端冒烟测试。
## Go 单测
运行全部内部测试:
```bash
go test ./internal/...
```
运行指定包:
```bash
go test ./internal/workflow
go test ./internal/multiagent
go test ./internal/handler
```
常见重点包:
- `internal/security`
- `internal/mcp`
- `internal/multiagent`
- `internal/workflow`
- `internal/knowledge`
- `internal/project`
- `internal/handler`
- `internal/c2`
## 构建测试
```bash
go build -o cyberstrike-ai ./cmd/server
```
构建通过不代表功能正确,但能发现入口、依赖和静态类型问题。
## 配置验证
启动前检查:
- YAML 缩进。
- 模型配置。
- 数据库路径可写。
- `tools_dir``roles_dir``skills_dir``agents_dir` 是否存在。
- HTTPS 证书路径是否正确。
启动后在 Web 设置页测试:
- OpenAI 兼容模型。
- 视觉模型。
- 工具列表。
- 外部 MCP 状态。
## API 手测
访问:
```text
/api-docs
```
重点验证:
- 登录。
- `/api/eino-agent/stream`
- `/api/config`
- `/api/config/tools`
- `/api/knowledge/search`
- `/api/monitor`
流式接口经过反向代理时要验证输出是否实时。
## 工具测试
新增或修改 `tools/*.yaml` 后:
- 在工具列表中确认 schema。
- 用低风险参数执行。
- 检查错误输出是否可读。
- 检查超时是否生效。
- 检查 HITL 是否按预期拦截。
不要用生产目标测试新工具。
## MCP 测试
外部 MCP
- stdio:先在终端独立运行命令。
- HTTP/SSE:用 curl 检查连通性。
- Web 页面启动后检查 `/api/external-mcp/stats`
- 在对话中确认工具是否可被 `tool_search` 找到。
## 知识库测试
步骤:
1. 放入小型 Markdown 文档。
2. 扫描知识库。
3. 重建索引。
4. 搜索文档中的关键词和同义表达。
5. 查看检索日志。
如果使用真实 embedding API,注意配额和速率限制。
## 前端冒烟
修改前端后至少验证:
- 登录和退出。
- 侧边栏对话列表。
- 新建对话和流式回复。
- 设置页面保存。
- 相关业务页面增删改查。
- 中英文切换。
- 浏览器控制台无明显错误。
## 高风险模块测试
C2、WebShell、终端、批量任务只能在授权测试环境验证。测试前确认:
- 目标是本机、靶机或演练环境。
- 命令无破坏性。
- HITL 策略符合预期。
- 测试后清理会话、payload、上传文件和任务结果。
## 测试金字塔
建议测试分层:
| 层级 | 目标 | 示例 |
| --- | --- | --- |
| 单元测试 | 纯逻辑正确 | 表达式、chunk、脱敏、超时格式 |
| Handler 测试 | HTTP 行为 | 参数校验、状态码、权限 |
| 集成测试 | 多模块协作 | 外部 MCP、知识库索引、HITL |
| 冒烟测试 | 用户路径可用 | 登录、对话、工具、设置 |
| 授权靶场测试 | 高风险能力安全 | C2、WebShell、终端 |
不要用端到端手测代替单元测试,也不要用单元测试代替高风险靶场验证。
## 回归测试重点
修改这些模块时必须扩大测试范围:
- `internal/handler/config.go`:测模型、知识库、MCP、C2、机器人配置应用。
- `internal/multiagent/`:测流式、工具调用、摘要、重试、HITL。
- `internal/security/`:测认证、Shell、超时、无输出。
- `internal/database/`:测旧数据兼容。
- `web/static/js/chat.js`:测对话、过程详情、攻击链、分组。
## 测试数据管理
不要用真实客户数据做测试。建议准备:
- 小型 Markdown 知识库样例。
- 本地假 MCP Server。
- 本地可控 HTTP 目标。
- 无害 WebShell 模拟端。
- 临时 SQLite 数据库。
测试完成后删除临时数据库和上传文件,避免污染开发环境。
## 失败用例比成功用例更重要
至少覆盖:
- 模型 API 401/429/500。
- MCP 进程启动失败。
- 工具超时。
- HITL 拒绝。
- 知识库索引中断。
- 数据库不可写。
- WebShell 目标返回非 200。
- C2 关闭时访问接口。
这些才是用户真实会遇到的问题。
## 源码锚点
已有测试集中在:
- `internal/handler/*_test.go`
- `internal/multiagent/*_test.go`
- `internal/workflow/*_test.go`
- `internal/knowledge/*_test.go`
- `internal/security/*_test.go`
- `internal/mcp/*_test.go`
- `internal/c2/*_test.go`
+224
View File
@@ -0,0 +1,224 @@
# 排错指南
本文按现象列出常见问题。优先查看服务日志、浏览器控制台和 `/api-docs` 中的接口响应。
## 无法访问页面
检查:
- 服务是否启动。
- 端口是否被占用。
- 配置中是否启用 HTTPS。
- 访问协议是否正确。
默认配置常见地址:
```text
https://127.0.0.1:8080/
```
如果使用自签证书,浏览器会提示不受信任,需要手动继续访问。
## 登录失败
检查:
- `config.yaml` 中的 `auth.password`
- 是否修改后未重启或未应用配置。
- 浏览器 Cookie 是否异常,可尝试无痕窗口。
- 审计日志中是否有登录失败节流。
生产环境忘记密码时,需要在服务器上修改 `config.yaml` 并重启服务。
## 模型无响应
检查:
- `openai.base_url` 是否包含正确路径,如 `/v1`
- `openai.api_key` 是否有效。
- `openai.model` 是否存在。
- 服务商是否支持当前 `reasoning` 字段。
可在系统设置中使用模型测试。若网关报 400,先尝试:
```yaml
openai:
reasoning:
mode: off
```
## 流式输出中断
常见原因:
- 反向代理缓冲 SSE。
- 模型网关超时。
- 浏览器网络断开。
- 上下文过大。
Nginx 需要:
```nginx
proxy_buffering off;
proxy_http_version 1.1;
```
## 工具执行失败
检查:
- 工具命令是否已安装到 PATH。
- `tools/*.yaml` 参数 schema 是否正确。
- 是否被 HITL 拒绝。
- 是否超过 `agent.tool_timeout_minutes`
- Shell 长时间无输出是否触发 `shell_no_output_timeout_seconds`
工具配置可参考 `tools/README.md`
## MCP 连不上
内置 MCP
- 检查 `mcp.enabled`
- 检查 `mcp.port`
- 检查 `auth_header``auth_header_value`
外部 MCP
- stdio:检查命令路径、工作目录、环境变量。
- HTTP/SSE:检查 URL、认证、网络连通性。
- 查看 `/api/external-mcp/stats`
## 知识库不可用
检查:
- `knowledge.enabled: true`
- embedding 配置是否正确。
- 是否已经扫描并重建索引。
- `data/knowledge.db` 是否可写。
- 嵌入服务是否 429 或超时。
如果索引大量失败,降低:
```yaml
knowledge:
indexing:
batch_size: 5
rate_limit_delay_ms: 600
```
## 机器人没有回复
检查:
- 对应平台 `robots.<platform>.enabled`
- 平台回调 URL 是否指向 `/api/robot/...`
- Token、secret、verify_token 是否一致。
- 服务器是否可被平台访问。
- 群聊是否需要 @ 机器人。
详细步骤见 [机器人使用说明](robot.md)。
## C2 监听器启动失败
检查:
- `c2.enabled`
- 端口是否被占用。
- 防火墙或安全组。
- 是否需要管理员权限绑定低端口。
关闭 C2 后 `/api/c2/*` 返回 503 是预期行为。
## WebShell 命令乱码
处理:
- 确认目标系统编码。
- 尝试更短命令。
- 使用 base64 包装输出。
- Windows 目标检查代码页。
## 数据库锁或写入失败
检查:
- `data/` 是否可写。
- 是否多个实例共用同一个 SQLite 文件。
- 磁盘是否满。
- 是否异常复制了 WAL/SHM 文件。
生产环境不要让多个进程同时写同一份 SQLite 数据库。
## 前端页面异常
检查:
- 浏览器控制台错误。
- 静态资源是否加载成功。
- 修改前端后是否刷新缓存。
- i18n key 是否缺失。
接口异常时打开 `/api-docs` 对照请求体。
## 诊断顺序
遇到问题时不要直接改配置,先定位层级:
1. 进程:服务是否还在,日志是否有 panic。
2. 网络:端口、HTTPS、反向代理、浏览器控制台。
3. 认证:`/api/auth/validate` 是否 200。
4. 配置:`/api/config` 是否能读,应用后是否报错。
5. 模型:模型测试是否通过。
6. 工具:工具列表和单个 schema 是否正常。
7. 数据库:`data/` 是否可写,有无锁。
8. 业务模块:知识库、MCP、C2、WebShell 分别测最小动作。
先定位层级,再改参数。否则容易把一个代理问题误判成模型问题。
## 最小诊断命令
```bash
# 进程和端口
lsof -i :8080
# 本机 HTTPS 是否通
curl -k -I https://127.0.0.1:8080/
# 静态资源是否通
curl -k -I https://127.0.0.1:8080/static/logo.png
# 查看数据库文件
ls -lh data/
```
如果经过 Nginx,再分别测代理地址和回源地址,确认问题在哪一层。
## 常见误判
- “模型坏了”:实际是 HITL 挂起等待审批。
- “工具没加载”:实际是 tool_search 隐藏了大部分工具。
- “知识库没效果”:实际是索引没重建或 risk_type 过滤过窄。
- “C2 接口坏了”:实际是 `c2.enabled: false`,返回 503 是正常保护。
- “配置保存了但没生效”:实际是监听端口/TLS 需要重启。
- “机器人不回复”:实际是平台侧没有正确配置回调 URL 或验签参数。
## 故障报告模板
提交问题时建议附:
```text
版本/提交:
启动方式:
访问方式:http/https/反向代理:
相关配置段:
复现步骤:
预期结果:
实际结果:
服务端日志:
浏览器控制台:
相关接口响应:
```
有了这些信息,定位速度通常会快很多。
+176
View File
@@ -0,0 +1,176 @@
# WebShell 管理
WebShell 管理用于保存授权目标的 WebShell 连接,并通过 Web 页面或 Agent 工具执行命令、文件操作和上下文分析。
## 基本流程
1. 在 WebShell 页面新增连接。
2. 填写名称、URL、密码或请求参数。
3. 测试连接。
4. 执行命令或文件操作。
5. 在对话中选择 WebShell 连接,让 AI 基于该连接辅助排查。
连接数据保存在 SQLite 中。
## 接口
主要 API
- `GET /api/webshell/connections`
- `POST /api/webshell/connections`
- `PUT /api/webshell/connections/:id`
- `DELETE /api/webshell/connections/:id`
- `GET /api/webshell/connections/:id/state`
- `PUT /api/webshell/connections/:id/state`
- `POST /api/webshell/exec`
- `POST /api/webshell/file`
- `GET /api/webshell/connections/:id/ai-history`
- `GET /api/webshell/connections/:id/ai-conversations`
## MCP 工具
系统会注册 WebShell MCP 工具,例如:
- `webshell_exec`:在连接上执行命令。
- `webshell_file_list`:列目录。
- `webshell_file_read`:读取文件。
- `webshell_file_write`:写文件。
- WebShell 连接管理工具。
Agent 使用这些工具时需要 `connection_id`。前端通常会把当前选中的连接注入上下文。
## 命令执行
执行命令前确认:
- 当前连接属于授权目标。
- 命令不会破坏业务。
- 输出中可能包含敏感信息。
- 长命令和交互式命令不适合 WebShell 通道。
建议先执行只读命令确认环境:
```bash
whoami
pwd
uname -a
id
```
Windows 目标可用:
```cmd
whoami
cd
ver
ipconfig
```
## 文件操作
文件操作包括列目录、读取、写入。建议:
- 写入前先备份原文件。
- 不在生产目标写入未经确认的脚本或二进制。
- 大文件优先通过专用下载/上传通道处理。
- 注意目标编码和换行符。
## AI 辅助
AI 可以帮助:
- 识别操作系统和当前权限。
- 规划只读枚举步骤。
- 分析命令输出。
- 汇总风险和修复建议。
不建议让 AI 自动执行:
- 删除文件。
- 修改业务配置。
- 持久化。
- 凭证抓取。
- 大范围扫描内网。
这些操作应由人工确认,并配合 HITL。
## 安全建议
- 仅保存授权目标连接。
- 给连接命名时包含项目、环境、目标。
- 演练结束后删除连接。
- 不把 WebShell 写入工具加入全局免审批白名单。
- 重要输出及时纳入项目事实或报告,随后清理敏感原始数据。
## 排错
连接失败:
- URL 不可达。
- 参数名或密码错误。
- 目标 WAF 拦截。
- 代理或 TLS 配置异常。
命令乱码:
- 检查目标系统编码。
- 尝试切换命令输出编码或使用 base64 包装。
AI 找不到连接:
- 确认前端已选中 WebShell 连接。
- 确认连接未被删除。
- 检查 `connection_id` 是否正确。
## 操作分层
WebShell 操作建议分成四层,不同层级使用不同审批策略:
| 层级 | 操作 | 风险 | 建议 |
| --- | --- | --- | --- |
| 识别 | `whoami``pwd`、系统版本 | 低 | 可自动 |
| 枚举 | 目录、进程、环境变量 | 中 | 限定路径和命令 |
| 读取 | 配置、日志、源码 | 中高 | 人工确认敏感性 |
| 写入/执行 | 写文件、运行脚本、删除 | 高 | 人工审批,说明回滚 |
不要把“WebShell 已经拿到了”理解成“后续操作都低风险”。WebShell 通常位于业务系统内部,误操作成本很高。
## 连接命名规范
建议命名:
```text
<项目>-<环境>-<目标>-<权限>-<日期>
```
示例:
```text
acme-staging-web01-www-20260707
```
糟糕命名:
```text
test
shell1
客户机器
```
AI 和人类审批都依赖上下文,连接名称含糊会直接放大误操作概率。
## AI 使用约束模板
给 WebShell 相关角色加一段约束:
```text
使用 WebShell 前先确认 connection_id、目标名称、当前目录和权限。默认只执行只读命令。任何写入、删除、上传、权限修改、持久化、凭证读取、内网探测都必须先给出目的、影响和回滚方式,并等待审批。
```
## 源码锚点
- Handler`internal/handler/webshell.go`
- 连接上下文:`internal/handler/webshell_context.go`
- 探测逻辑:`internal/handler/webshell_probe.go`
- OS/编码处理测试:`internal/handler/webshell_os_test.go``internal/handler/webshell_encoding_test.go`
- MCP 工具注册:`internal/app/app.go``registerWebshellTools`
@@ -1,6 +1,6 @@
# CyberStrikeAI 图编排使用说明
[English](workflow-graph_en.md)
[English](../en-US/workflow-graph.md)
本文档说明 **图编排(Graph Orchestration** 的完整使用方式:如何在画布上搭建流程、配置各类型节点、在节点之间传递数据,以及如何将流程绑定到角色并自动运行。
Binary file not shown.

Before

Width:  |  Height:  |  Size: 477 KiB

After

Width:  |  Height:  |  Size: 741 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 317 KiB

After

Width:  |  Height:  |  Size: 420 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 656 KiB

After

Width:  |  Height:  |  Size: 551 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 326 KiB

After

Width:  |  Height:  |  Size: 347 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 493 KiB

After

Width:  |  Height:  |  Size: 498 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 598 KiB

After

Width:  |  Height:  |  Size: 775 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 451 KiB

After

Width:  |  Height:  |  Size: 358 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 265 KiB

After

Width:  |  Height:  |  Size: 86 KiB

+7 -7
View File
@@ -295,11 +295,11 @@ func New(cfg *config.Config, log *logger.Logger, configPath string) (*App, error
return
}
// 只有在没有索引时才自动重建
// 冷启动:仅为尚无向量的知识项构建索引(与 IndexMissing 语义一致)
log.Logger.Info("未检测到知识库索引,开始自动构建索引")
ctx := context.Background()
if err := knowledgeIndexer.RebuildIndex(ctx); err != nil {
log.Logger.Warn("建知识库索引失败", zap.Error(err))
if err := knowledgeIndexer.IndexMissing(ctx); err != nil {
log.Logger.Warn("自动构建知识库索引失败", zap.Error(err))
}
}()
}
@@ -1071,7 +1071,7 @@ func setupRoutes(
})
return
}
app.knowledgeHandler.RebuildIndex(c)
app.knowledgeHandler.StartIndex(c)
})
knowledgeRoutes.POST("/scan", func(c *gin.Context) {
if app.knowledgeHandler == nil {
@@ -1961,11 +1961,11 @@ func initializeKnowledge(
return
}
// 只有在没有索引时才自动重建
// 冷启动:仅为尚无向量的知识项构建索引(与 IndexMissing 语义一致)
logger.Info("未检测到知识库索引,开始自动构建索引")
ctx := context.Background()
if err := knowledgeIndexer.RebuildIndex(ctx); err != nil {
logger.Warn("建知识库索引失败", zap.Error(err))
if err := knowledgeIndexer.IndexMissing(ctx); err != nil {
logger.Warn("自动构建知识库索引失败", zap.Error(err))
}
}()
+97 -14
View File
@@ -455,15 +455,15 @@ type MultiAgentAPIUpdate struct {
// RobotsConfig 机器人配置(企业微信、钉钉、飞书、微信 iLink、Telegram、Slack、Discord、QQ 等)
type RobotsConfig struct {
Session RobotSessionConfig `yaml:"session,omitempty" json:"session,omitempty"` // 机器人会话隔离策略
Wechat RobotWechatConfig `yaml:"wechat,omitempty" json:"wechat,omitempty"` // 微信(iLink 扫码绑定)
Wecom RobotWecomConfig `yaml:"wecom,omitempty" json:"wecom,omitempty"` // 企业微信
Dingtalk RobotDingtalkConfig `yaml:"dingtalk,omitempty" json:"dingtalk,omitempty"` // 钉钉
Lark RobotLarkConfig `yaml:"lark,omitempty" json:"lark,omitempty"` // 飞书
Telegram RobotTelegramConfig `yaml:"telegram,omitempty" json:"telegram,omitempty"` // Telegram
Slack RobotSlackConfig `yaml:"slack,omitempty" json:"slack,omitempty"` // Slack
Discord RobotDiscordConfig `yaml:"discord,omitempty" json:"discord,omitempty"` // Discord
QQ RobotQQConfig `yaml:"qq,omitempty" json:"qq,omitempty"` // QQ 机器人
Session RobotSessionConfig `yaml:"session,omitempty" json:"session,omitempty"` // 机器人会话隔离策略
Wechat RobotWechatConfig `yaml:"wechat,omitempty" json:"wechat,omitempty"` // 微信(iLink 扫码绑定)
Wecom RobotWecomConfig `yaml:"wecom,omitempty" json:"wecom,omitempty"` // 企业微信
Dingtalk RobotDingtalkConfig `yaml:"dingtalk,omitempty" json:"dingtalk,omitempty"` // 钉钉
Lark RobotLarkConfig `yaml:"lark,omitempty" json:"lark,omitempty"` // 飞书
Telegram RobotTelegramConfig `yaml:"telegram,omitempty" json:"telegram,omitempty"` // Telegram
Slack RobotSlackConfig `yaml:"slack,omitempty" json:"slack,omitempty"` // Slack
Discord RobotDiscordConfig `yaml:"discord,omitempty" json:"discord,omitempty"` // Discord
QQ RobotQQConfig `yaml:"qq,omitempty" json:"qq,omitempty"` // QQ 机器人
}
// RobotWechatConfig 微信 iLink 机器人配置(个人微信 ClawBot / iLink 协议)
@@ -540,9 +540,9 @@ type RobotTelegramConfig struct {
// RobotSlackConfig Slack 机器人配置(Socket Mode,无需公网回调)
type RobotSlackConfig struct {
Enabled bool `yaml:"enabled" json:"enabled"`
BotToken string `yaml:"bot_token" json:"bot_token"` // xoxb-
AppToken string `yaml:"app_token" json:"app_token"` // xapp-connections:write
Enabled bool `yaml:"enabled" json:"enabled"`
BotToken string `yaml:"bot_token" json:"bot_token"` // xoxb-
AppToken string `yaml:"app_token" json:"app_token"` // xapp-connections:write
}
// RobotDiscordConfig Discord 机器人配置(Gateway WebSocket
@@ -670,6 +670,8 @@ type AgentConfig struct {
// tool_whitelist 可在侧栏「应用」时合并写入 config.yaml 并立即生效。
// audit_agent_prompt / audit_agent_prompt_review_edit 可在人机协同页编辑并立即生效;空则使用内置默认。
type HitlConfig struct {
// AuditModel 审计 Agent 专用模型;字段留空时继承 OpenAI 主配置,便于用小模型做审批。
AuditModel OpenAIConfig `yaml:"audit_model,omitempty" json:"audit_model,omitempty"`
// ToolWhitelist 全局免审批工具名(与白名单内工具不触发 HITL 审批)。
ToolWhitelist []string `yaml:"tool_whitelist,omitempty" json:"tool_whitelist,omitempty"`
// AuditAgentPrompt 审批模式(approval)下审计 Agent 系统提示词。
@@ -703,6 +705,28 @@ func (h HitlConfig) RetentionDaysEffective() int {
return *h.RetentionDays
}
// AuditModelEffective returns the audit-agent model config with empty fields inherited from the main model config.
func (h HitlConfig) AuditModelEffective(main OpenAIConfig) OpenAIConfig {
out := main
am := h.AuditModel
if strings.TrimSpace(am.Provider) != "" {
out.Provider = strings.TrimSpace(am.Provider)
}
if strings.TrimSpace(am.BaseURL) != "" {
out.BaseURL = strings.TrimSpace(am.BaseURL)
}
if strings.TrimSpace(am.APIKey) != "" {
out.APIKey = strings.TrimSpace(am.APIKey)
}
if strings.TrimSpace(am.Model) != "" {
out.Model = strings.TrimSpace(am.Model)
}
if am.MaxTotalTokens > 0 {
out.MaxTotalTokens = am.MaxTotalTokens
}
return out
}
const hitlAuditAgentPromptBase = `你是 CyberStrikeAI 人机协同审计 Agent审查 Agent 即将执行的工具调用是否会对系统造成实质性损害
你会收到 JSON包含 hitlModetoolNamearguments/argumentsObjuserMessagethinkingreasoningChainplanning 等字段
@@ -1074,11 +1098,11 @@ func PersistAuthPassword(path, password string) error {
if strings.HasPrefix(strings.TrimSpace(line), "password:") {
prefix := line[:len(line)-len(strings.TrimLeft(line, " "))]
comment := ""
if idx := strings.Index(line, "#"); idx >= 0 {
if idx := yamlLineCommentIndex(line); idx >= 0 {
comment = strings.TrimRight(line[idx:], " ")
}
newLine := fmt.Sprintf("%spassword: %s", prefix, password)
newLine := fmt.Sprintf("%spassword: %s", prefix, quoteYAMLString(password))
if comment != "" {
if !strings.HasPrefix(comment, " ") {
newLine += " "
@@ -1093,6 +1117,65 @@ func PersistAuthPassword(path, password string) error {
return os.WriteFile(path, []byte(strings.Join(lines, "\n")), 0644)
}
func quoteYAMLString(value string) string {
node := yaml.Node{
Kind: yaml.ScalarNode,
Tag: "!!str",
Style: yaml.DoubleQuotedStyle,
Value: value,
}
data, err := yaml.Marshal(&node)
if err != nil {
return strconv.Quote(value)
}
return strings.TrimSuffix(string(data), "\n")
}
func yamlLineCommentIndex(line string) int {
inSingleQuote := false
inDoubleQuote := false
escaped := false
for i, r := range line {
if inDoubleQuote {
if escaped {
escaped = false
continue
}
if r == '\\' {
escaped = true
continue
}
if r == '"' {
inDoubleQuote = false
}
continue
}
if inSingleQuote {
if r == '\'' {
inSingleQuote = false
}
continue
}
switch r {
case '"':
inDoubleQuote = true
case '\'':
inSingleQuote = true
case '#':
if i == 0 || isYAMLWhitespace(line[i-1]) {
return i
}
}
}
return -1
}
func isYAMLWhitespace(b byte) bool {
return b == ' ' || b == '\t'
}
func PrintGeneratedPasswordWarning(password string, persisted bool, persistErr string) {
if strings.TrimSpace(password) == "" {
return
+93
View File
@@ -0,0 +1,93 @@
package config
import (
"os"
"path/filepath"
"strings"
"testing"
)
func TestPersistAuthPasswordQuotesYAMLSpecialCharacters(t *testing.T) {
dir := t.TempDir()
path := filepath.Join(dir, "config.yaml")
initial := strings.Join([]string{
"server:",
" host: 0.0.0.0",
"auth:",
" password: old-password # Web 登录密码",
" session_duration_hours: 12",
"log:",
" level: info",
"",
}, "\n")
if err := os.WriteFile(path, []byte(initial), 0644); err != nil {
t.Fatalf("write config: %v", err)
}
want := `@abc:def # still password`
if err := PersistAuthPassword(path, want); err != nil {
t.Fatalf("PersistAuthPassword: %v", err)
}
data, err := os.ReadFile(path)
if err != nil {
t.Fatalf("read config: %v", err)
}
if !strings.Contains(string(data), `password: "@abc:def # still password" # Web 登录密码`) {
t.Fatalf("password was not safely quoted or comment was not preserved:\n%s", data)
}
cfg, err := Load(path)
if err != nil {
t.Fatalf("Load after PersistAuthPassword: %v", err)
}
if cfg.Auth.Password != want {
t.Fatalf("Auth.Password = %q, want %q", cfg.Auth.Password, want)
}
}
func TestPersistAuthPasswordDoesNotTreatQuotedHashAsComment(t *testing.T) {
dir := t.TempDir()
path := filepath.Join(dir, "config.yaml")
initial := strings.Join([]string{
"auth:",
` password: "old#password"`,
" session_duration_hours: 12",
"",
}, "\n")
if err := os.WriteFile(path, []byte(initial), 0644); err != nil {
t.Fatalf("write config: %v", err)
}
if err := PersistAuthPassword(path, "new-password"); err != nil {
t.Fatalf("PersistAuthPassword: %v", err)
}
data, err := os.ReadFile(path)
if err != nil {
t.Fatalf("read config: %v", err)
}
if strings.Contains(string(data), "#password") {
t.Fatalf("old quoted password fragment was incorrectly preserved as a comment:\n%s", data)
}
}
func TestHitlAuditModelEffectiveFallsBackToMainConfig(t *testing.T) {
main := OpenAIConfig{
Provider: "openai",
BaseURL: "https://api.example.com/v1",
APIKey: "main-key",
Model: "large-model",
}
got := (HitlConfig{
AuditModel: OpenAIConfig{Model: "small-reviewer"},
}).AuditModelEffective(main)
if got.Provider != main.Provider || got.BaseURL != main.BaseURL || got.APIKey != main.APIKey {
t.Fatalf("expected provider/base_url/api_key to inherit main config, got %+v", got)
}
if got.Model != "small-reviewer" {
t.Fatalf("expected audit model override, got %q", got.Model)
}
}
+39 -13
View File
@@ -246,7 +246,7 @@ type GetConfigResponse struct {
Knowledge config.KnowledgeConfig `json:"knowledge"`
Robots config.RobotsConfig `json:"robots,omitempty"`
MultiAgent config.MultiAgentPublic `json:"multi_agent,omitempty"`
C2 config.C2Public `json:"c2"`
C2 config.C2Public `json:"c2"`
}
// ToolConfigInfo 工具配置信息
@@ -320,7 +320,7 @@ func (h *ConfigHandler) GetConfig(c *gin.Context) {
}
multiPub := config.MultiAgentPublic{
Enabled: h.config.MultiAgent.Enabled,
RobotDefaultAgentMode: config.NormalizeRobotAgentMode(h.config.MultiAgent),
RobotDefaultAgentMode: config.NormalizeRobotAgentMode(h.config.MultiAgent),
BatchUseMultiAgent: h.config.MultiAgent.BatchUseMultiAgent,
SubAgentCount: subAgentCount,
Orchestration: config.NormalizeMultiAgentOrchestration(h.config.MultiAgent.Orchestration),
@@ -673,16 +673,17 @@ func (h *ConfigHandler) GetTools(c *gin.Context) {
// UpdateConfigRequest 更新配置请求
type UpdateConfigRequest struct {
OpenAI *config.OpenAIConfig `json:"openai,omitempty"`
Vision *config.VisionConfig `json:"vision,omitempty"`
FOFA *config.FofaConfig `json:"fofa,omitempty"`
MCP *config.MCPConfig `json:"mcp,omitempty"`
Tools []ToolEnableStatus `json:"tools,omitempty"`
Agent *AgentConfigUpdate `json:"agent,omitempty"`
Knowledge *config.KnowledgeConfig `json:"knowledge,omitempty"`
Robots *config.RobotsConfig `json:"robots,omitempty"`
MultiAgent *config.MultiAgentAPIUpdate `json:"multi_agent,omitempty"`
C2 *config.C2APIUpdate `json:"c2,omitempty"`
OpenAI *config.OpenAIConfig `json:"openai,omitempty"`
Vision *config.VisionConfig `json:"vision,omitempty"`
FOFA *config.FofaConfig `json:"fofa,omitempty"`
MCP *config.MCPConfig `json:"mcp,omitempty"`
Tools []ToolEnableStatus `json:"tools,omitempty"`
Agent *AgentConfigUpdate `json:"agent,omitempty"`
Hitl *config.HitlConfig `json:"hitl,omitempty"`
Knowledge *config.KnowledgeConfig `json:"knowledge,omitempty"`
Robots *config.RobotsConfig `json:"robots,omitempty"`
MultiAgent *config.MultiAgentAPIUpdate `json:"multi_agent,omitempty"`
C2 *config.C2APIUpdate `json:"c2,omitempty"`
}
// AgentConfigUpdate 用于 PATCH /api/config 的 agent 段:仅 JSON 中出现的字段(指针非 nil)覆盖内存配置。
@@ -775,6 +776,25 @@ func (h *ConfigHandler) UpdateConfig(c *gin.Context) {
}
}
if req.Hitl != nil {
h.config.Hitl.AuditModel = req.Hitl.AuditModel
h.config.Hitl.ToolWhitelist = mergeHitlToolWhitelistSlice(nil, req.Hitl.ToolWhitelist)
h.config.Hitl.DefaultReviewer = req.Hitl.EffectiveDefaultReviewer()
h.config.Hitl.AuditAgentPrompt = strings.TrimSpace(req.Hitl.AuditAgentPrompt)
h.config.Hitl.AuditAgentPromptReviewEdit = strings.TrimSpace(req.Hitl.AuditAgentPromptReviewEdit)
if req.Hitl.RetentionDays != nil {
v := *req.Hitl.RetentionDays
if v < 0 {
v = 0
}
h.config.Hitl.RetentionDays = &v
}
h.logger.Info("更新HITL配置",
zap.String("default_reviewer", h.config.Hitl.DefaultReviewer),
zap.Int("tool_whitelist", len(h.config.Hitl.ToolWhitelist)),
)
}
// 更新Knowledge配置
if req.Knowledge != nil {
// 保存旧的嵌入模型配置(用于检测变更)
@@ -1471,7 +1491,7 @@ func (h *ConfigHandler) ApplyConfig(c *gin.Context) {
Result: "success",
Message: "配置已应用",
Detail: map[string]interface{}{
"tools_count": len(h.config.Security.Tools),
"tools_count": len(h.config.Security.Tools),
"knowledge_enabled": h.config.Knowledge.Enabled,
"c2_enabled": h.config.C2.EnabledEffective(),
},
@@ -1804,9 +1824,15 @@ func (h *ConfigHandler) MergeHitlToolWhitelistIntoConfig(add []string) error {
func updateHitlConfig(doc *yaml.Node, cfg config.HitlConfig) {
root := doc.Content[0]
hitlNode := ensureMap(root, "hitl")
auditModelNode := ensureMap(hitlNode, "audit_model")
setStringInMap(auditModelNode, "provider", cfg.AuditModel.Provider)
setStringInMap(auditModelNode, "base_url", cfg.AuditModel.BaseURL)
setStringInMap(auditModelNode, "api_key", cfg.AuditModel.APIKey)
setStringInMap(auditModelNode, "model", cfg.AuditModel.Model)
// flow 样式 [a, b, c] 单行展示,工具多时比块序列省行数
setFlowStringSliceInMap(hitlNode, "tool_whitelist", cfg.ToolWhitelist)
setStringInMap(hitlNode, "default_reviewer", cfg.EffectiveDefaultReviewer())
setIntInMap(hitlNode, "retention_days", cfg.RetentionDaysEffective())
setStringInMap(hitlNode, "audit_agent_prompt", cfg.AuditAgentPrompt)
setStringInMap(hitlNode, "audit_agent_prompt_review_edit", cfg.AuditAgentPromptReviewEdit)
}
+15 -12
View File
@@ -10,6 +10,7 @@ import (
"time"
"cyberstrike-ai/internal/config"
"cyberstrike-ai/internal/openai"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
@@ -26,7 +27,8 @@ func (h *AgentHandler) auditAgentReview(ctx context.Context, hitlMode, toolName
if h.config != nil {
prompt = h.config.Hitl.EffectiveAuditAgentPromptForMode(mode)
}
if h.auditLLM == nil {
llmCfg := h.auditLLMConfig()
if strings.TrimSpace(llmCfg.APIKey) == "" || strings.TrimSpace(llmCfg.Model) == "" {
return hitlDecision{Decision: "reject", Comment: "audit agent: LLM 未配置"}
}
if ctx == nil {
@@ -37,7 +39,7 @@ func (h *AgentHandler) auditAgentReview(ctx context.Context, hitlMode, toolName
userContent := buildAuditAgentReviewInput(mode, toolName, payload)
requestBody := map[string]interface{}{
"model": h.auditLLMModel(),
"model": strings.TrimSpace(llmCfg.Model),
"messages": []map[string]interface{}{
{"role": "system", "content": prompt},
{"role": "user", "content": userContent},
@@ -56,7 +58,8 @@ func (h *AgentHandler) auditAgentReview(ctx context.Context, hitlMode, toolName
} `json:"message"`
} `json:"choices"`
}
if err := h.auditLLM.ChatCompletion(callCtx, requestBody, &apiResponse); err != nil {
client := openai.NewClient(&llmCfg, nil, h.logger)
if err := client.ChatCompletion(callCtx, requestBody, &apiResponse); err != nil {
h.logger.Warn("审计 Agent LLM 调用失败", zap.Error(err), zap.String("tool", toolName))
return hitlDecision{
Decision: "reject",
@@ -99,11 +102,11 @@ func (h *AgentHandler) auditAgentReview(ctx context.Context, hitlMode, toolName
return dec
}
func (h *AgentHandler) auditLLMModel() string {
if h.config != nil && strings.TrimSpace(h.config.OpenAI.Model) != "" {
return strings.TrimSpace(h.config.OpenAI.Model)
func (h *AgentHandler) auditLLMConfig() config.OpenAIConfig {
if h != nil && h.config != nil {
return h.config.Hitl.AuditModelEffective(h.config.OpenAI)
}
return ""
return config.OpenAIConfig{}
}
func buildAuditAgentReviewInput(hitlMode, toolName string, payload map[string]interface{}) string {
@@ -338,11 +341,11 @@ func (h *AgentHandler) UpdateHITLAuditStrategy(c *gin.Context) {
h.config.Hitl.AuditAgentPromptReviewEdit = reviewEditPrompt
}
c.JSON(http.StatusOK, gin.H{
"ok": true,
"auditAgentPrompt": config.HitlConfig{AuditAgentPrompt: approvalPrompt}.EffectiveAuditAgentPromptForMode("approval"),
"auditAgentPromptCustom": approvalPrompt != "",
"auditAgentPromptReviewEdit": config.HitlConfig{AuditAgentPromptReviewEdit: reviewEditPrompt}.EffectiveAuditAgentPromptForMode("review_edit"),
"auditAgentPromptReviewEditCustom": reviewEditPrompt != "",
"ok": true,
"auditAgentPrompt": config.HitlConfig{AuditAgentPrompt: approvalPrompt}.EffectiveAuditAgentPromptForMode("approval"),
"auditAgentPromptCustom": approvalPrompt != "",
"auditAgentPromptReviewEdit": config.HitlConfig{AuditAgentPromptReviewEdit: reviewEditPrompt}.EffectiveAuditAgentPromptForMode("review_edit"),
"auditAgentPromptReviewEditCustom": reviewEditPrompt != "",
})
}
+43 -7
View File
@@ -4,6 +4,7 @@ import (
"context"
"fmt"
"net/http"
"strings"
"time"
"cyberstrike-ai/internal/audit"
@@ -316,20 +317,55 @@ func (h *KnowledgeHandler) DeleteItem(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"message": "删除成功"})
}
// RebuildIndex 重建索引
func (h *KnowledgeHandler) RebuildIndex(c *gin.Context) {
// 异步重建索引
// StartIndex 构建知识库向量索引。默认仅补齐尚无向量的知识项;mode=full 时全量重建。
func (h *KnowledgeHandler) StartIndex(c *gin.Context) {
if err := h.indexer.TryBeginIndexRun(); err != nil {
c.JSON(http.StatusConflict, gin.H{"error": "已有索引任务正在进行,请等待完成"})
return
}
mode := strings.TrimSpace(c.Query("mode"))
if mode == "" {
mode = "missing"
}
if mode != "full" && mode != "missing" {
h.indexer.FinishIndexRun()
c.JSON(http.StatusBadRequest, gin.H{"error": "无效的 mode 参数,可选值:missing、full"})
return
}
fullRebuild := mode == "full"
message := "索引构建已开始,将在后台进行"
auditAction := "index_build"
auditDetail := "构建知识库索引"
if fullRebuild {
message = "全量索引重建已开始,将在后台进行"
auditAction = "index_rebuild_full"
auditDetail = "全量重建知识库索引"
}
go func() {
defer h.indexer.FinishIndexRun()
ctx := context.Background()
if err := h.indexer.RebuildIndex(ctx); err != nil {
h.logger.Error("重建索引失败", zap.Error(err))
var err error
if fullRebuild {
err = h.indexer.RunRebuildIndex(ctx)
} else {
err = h.indexer.RunIndexMissing(ctx)
}
if err != nil {
if fullRebuild {
h.logger.Error("全量重建索引失败", zap.Error(err))
} else {
h.logger.Error("构建知识库索引失败", zap.Error(err))
}
}
}()
if h.audit != nil {
h.audit.RecordOK(c, "knowledge", "index_rebuild", "重建知识库索引", "knowledge", "", nil)
h.audit.RecordOK(c, "knowledge", auditAction, auditDetail, "knowledge", "", nil)
}
c.JSON(http.StatusOK, gin.H{"message": "索引重建已开始,将在后台进行"})
c.JSON(http.StatusOK, gin.H{"message": message, "mode": mode})
}
// ScanKnowledgeBase 扫描知识库
+23 -4
View File
@@ -4416,16 +4416,35 @@ func (h *OpenAPIHandler) GetOpenAPISpec(c *gin.Context) {
"/api/knowledge/index": map[string]interface{}{
"post": map[string]interface{}{
"tags": []string{"知识库"},
"summary": "建索引",
"description": "重新构建知识库索引",
"operationId": "rebuildIndex",
"summary": "建索引",
"description": "构建知识库向量索引。默认仅处理尚无向量的知识项;mode=full 时全量重建。",
"operationId": "startKnowledgeIndex",
"parameters": []map[string]interface{}{
{
"name": "mode",
"in": "query",
"required": false,
"description": "索引模式:missing(默认,补齐缺失向量)或 full(全量重建)",
"schema": map[string]interface{}{
"type": "string",
"enum": []string{"missing", "full"},
"default": "missing",
},
},
},
"responses": map[string]interface{}{
"200": map[string]interface{}{
"description": "重建索引任务已启动",
"description": "索引任务已启动",
},
"400": map[string]interface{}{
"description": "无效的 mode 参数",
},
"401": map[string]interface{}{
"description": "未授权",
},
"409": map[string]interface{}{
"description": "已有索引任务正在进行",
},
},
},
},
+13 -1
View File
@@ -11,6 +11,7 @@ var apiDocI18nTagToKey = map[string]string{
"知识库": "knowledgeBase", "MCP": "mcp",
"FOFA信息收集": "fofaRecon", "终端": "terminal", "WebShell管理": "webshellManagement",
"对话附件": "chatUploads", "机器人集成": "robotIntegration", "多代理Markdown": "markdownAgents",
"项目管理": "projectManagement",
}
var apiDocI18nSummaryToKey = map[string]string{
@@ -42,7 +43,7 @@ var apiDocI18nSummaryToKey = map[string]string{
"设置对话置顶": "pinConversation", "设置分组置顶": "pinGroup", "设置分组中对话的置顶": "pinGroupConversation",
"获取分类": "getCategories", "列出知识项": "listKnowledgeItems", "创建知识项": "createKnowledgeItem",
"获取知识项": "getKnowledgeItem", "更新知识项": "updateKnowledgeItem", "删除知识项": "deleteKnowledgeItem",
"获取索引状态": "getIndexStatus", "建索引": "rebuildIndex", "扫描知识库": "scanKnowledgeBase",
"获取索引状态": "getIndexStatus", "建索引": "startKnowledgeIndex", "扫描知识库": "scanKnowledgeBase",
"搜索知识库": "searchKnowledgeBase", "基础搜索": "basicSearch", "按风险类型搜索": "searchByRiskType",
"获取检索日志": "getRetrievalLogs", "删除检索日志": "deleteRetrievalLog",
"MCP端点": "mcpEndpoint", "列出所有工具": "listAllTools", "调用工具": "invokeTool", "初始化连接": "initConnection",
@@ -70,6 +71,12 @@ var apiDocI18nSummaryToKey = map[string]string{
"列出技能包文件": "listSkillPackageFiles", "获取技能包文件内容": "getSkillPackageFile", "写入技能包文件": "putSkillPackageFile",
"批量获取工具名称": "batchGetToolNames",
"获取知识库统计": "getKnowledgeStats",
"列出项目": "listProjects", "创建项目": "createProject", "获取项目": "getProject",
"更新项目": "updateProject", "删除项目": "deleteProject",
"列出或按 key 获取事实": "listProjectFacts", "创建/更新事实": "upsertProjectFact",
"获取项目事实攻击路径图": "getProjectFactGraph", "列出项目全部事实边": "listProjectFactEdges",
"添加事实边": "createProjectFactEdge", "删除事实边": "deleteProjectFactEdge",
"将对话攻击链沉淀到项目事实图": "promoteAttackChainToProject",
}
var apiDocI18nResponseDescToKey = map[string]string{
@@ -97,6 +104,11 @@ var apiDocI18nResponseDescToKey = map[string]string{
"重命名成功": "renameSuccess", "验证成功,返回解密后的echostr": "wecomVerifySuccess",
"处理成功": "processSuccess", "代理不存在": "agentNotFound", "保存成功": "saveSuccess",
"操作结果": "operationResult", "执行结果": "executionResult", "连接不存在": "connectionNotFound",
"项目列表": "projectList", "项目详情": "projectDetail",
"事实列表或单条(可含 link_counts / outgoing_links": "projectFactList",
"成功": "success", "nodes + edges": "factGraphNodesEdges",
"边列表": "edgeList", "边已创建": "edgeCreated",
"沉淀结果(facts/edges/graph": "promoteAttackChainResult",
}
// enrichSpecWithI18nKeys 在 spec 的每个 operation 上写入 x-i18n-tags、x-i18n-summary
+105 -22
View File
@@ -213,9 +213,13 @@ func (idx *Indexer) HasIndex() (bool, error) {
return count > 0, nil
}
// RebuildIndex 重建所有索引
func (idx *Indexer) RebuildIndex(ctx context.Context) error {
func (idx *Indexer) beginIndexRun() error {
idx.rebuildMu.Lock()
defer idx.rebuildMu.Unlock()
if idx.isRebuilding {
return fmt.Errorf("索引任务已在进行中")
}
idx.isRebuilding = true
idx.rebuildTotalItems = 0
idx.rebuildCurrent = 0
@@ -223,41 +227,124 @@ func (idx *Indexer) RebuildIndex(ctx context.Context) error {
idx.rebuildStartTime = time.Now()
idx.rebuildLastItemID = ""
idx.rebuildLastChunks = 0
idx.rebuildMu.Unlock()
return nil
}
// TryBeginIndexRun 同步占用索引任务槽位;调用方必须在后台任务结束时调用 FinishIndexRun。
func (idx *Indexer) TryBeginIndexRun() error {
return idx.beginIndexRun()
}
func (idx *Indexer) FinishIndexRun() {
idx.rebuildMu.Lock()
idx.isRebuilding = false
idx.rebuildMu.Unlock()
}
func (idx *Indexer) resetLastError() {
idx.mu.Lock()
idx.lastError = ""
idx.lastErrorTime = time.Time{}
idx.errorCount = 0
idx.mu.Unlock()
}
rows, err := idx.db.Query("SELECT id FROM knowledge_base_items")
func (idx *Indexer) setIndexRunTotal(total int) {
idx.rebuildMu.Lock()
idx.rebuildTotalItems = total
idx.rebuildMu.Unlock()
}
// IndexMissing 为尚无向量的知识项构建索引(默认推荐路径,适合冷启动与中断续跑)。
func (idx *Indexer) IndexMissing(ctx context.Context) error {
if err := idx.beginIndexRun(); err != nil {
return err
}
defer idx.FinishIndexRun()
return idx.runIndexMissing(ctx)
}
// RebuildIndex 全量重建所有知识项索引(显式 opt-in,成本更高)。
func (idx *Indexer) RebuildIndex(ctx context.Context) error {
if err := idx.beginIndexRun(); err != nil {
return err
}
defer idx.FinishIndexRun()
return idx.runRebuildIndex(ctx)
}
// RunRebuildIndex 在已占用索引任务槽位后执行全量重建(供 HTTP handler 后台任务使用)。
func (idx *Indexer) RunRebuildIndex(ctx context.Context) error {
return idx.runRebuildIndex(ctx)
}
// RunIndexMissing 在已占用索引任务槽位后执行缺失索引补齐(供 HTTP handler 后台任务使用)。
func (idx *Indexer) RunIndexMissing(ctx context.Context) error {
return idx.runIndexMissing(ctx)
}
func (idx *Indexer) runRebuildIndex(ctx context.Context) error {
idx.resetLastError()
rows, err := idx.db.QueryContext(ctx, "SELECT id FROM knowledge_base_items ORDER BY updated_at ASC, id ASC")
if err != nil {
idx.rebuildMu.Lock()
idx.isRebuilding = false
idx.rebuildMu.Unlock()
return fmt.Errorf("查询知识项失败:%w", err)
}
defer rows.Close()
itemIDs, err := scanKnowledgeItemIDs(rows)
if err != nil {
return err
}
idx.setIndexRunTotal(len(itemIDs))
idx.logger.Info("开始重建索引", zap.Int("totalItems", len(itemIDs)))
return idx.indexItemIDs(ctx, itemIDs, "索引重建完成")
}
func (idx *Indexer) runIndexMissing(ctx context.Context) error {
idx.resetLastError()
rows, err := idx.db.QueryContext(ctx, `
SELECT i.id
FROM knowledge_base_items i
LEFT JOIN knowledge_embeddings e ON e.item_id = i.id
WHERE e.item_id IS NULL
ORDER BY i.updated_at ASC, i.id ASC
`)
if err != nil {
return fmt.Errorf("查询未索引知识项失败:%w", err)
}
defer rows.Close()
itemIDs, err := scanKnowledgeItemIDs(rows)
if err != nil {
return fmt.Errorf("扫描未索引知识项 ID 失败:%w", err)
}
idx.setIndexRunTotal(len(itemIDs))
idx.logger.Info("开始补齐缺失索引", zap.Int("totalItems", len(itemIDs)))
return idx.indexItemIDs(ctx, itemIDs, "索引构建完成")
}
func scanKnowledgeItemIDs(rows *sql.Rows) ([]string, error) {
var itemIDs []string
for rows.Next() {
var id string
if err := rows.Scan(&id); err != nil {
idx.rebuildMu.Lock()
idx.isRebuilding = false
idx.rebuildMu.Unlock()
return fmt.Errorf("扫描知识项 ID 失败:%w", err)
return nil, fmt.Errorf("扫描知识项 ID 失败:%w", err)
}
itemIDs = append(itemIDs, id)
}
if err := rows.Err(); err != nil {
return nil, fmt.Errorf("扫描知识项 ID 失败:%w", err)
}
return itemIDs, nil
}
idx.rebuildMu.Lock()
idx.rebuildTotalItems = len(itemIDs)
idx.rebuildMu.Unlock()
idx.logger.Info("开始重建索引", zap.Int("totalItems", len(itemIDs)))
func (idx *Indexer) indexItemIDs(ctx context.Context, itemIDs []string, doneMessage string) error {
failedCount := 0
consecutiveFailures := 0
maxConsecutiveFailures := 5
@@ -329,11 +416,7 @@ func (idx *Indexer) RebuildIndex(ctx context.Context) error {
}
}
idx.rebuildMu.Lock()
idx.isRebuilding = false
idx.rebuildMu.Unlock()
idx.logger.Info("索引重建完成", zap.Int("totalItems", len(itemIDs)), zap.Int("failedCount", failedCount))
idx.logger.Info(doneMessage, zap.Int("totalItems", len(itemIDs)), zap.Int("failedCount", failedCount))
return nil
}
@@ -0,0 +1,20 @@
package knowledge
import "testing"
func TestIndexerRejectsConcurrentIndexRuns(t *testing.T) {
idx := &Indexer{}
if err := idx.beginIndexRun(); err != nil {
t.Fatalf("first index run should start: %v", err)
}
if err := idx.beginIndexRun(); err == nil {
t.Fatal("second index run should be rejected while one is active")
}
idx.FinishIndexRun()
if err := idx.beginIndexRun(); err != nil {
t.Fatalf("index run should start again after finish: %v", err)
}
idx.FinishIndexRun()
}
+19 -10
View File
@@ -407,6 +407,18 @@ func (e *Executor) buildCommandArgs(toolName string, toolConfig *config.ToolConf
}
}
formattedValue := e.formatParamValue(param, value)
if strings.TrimSpace(formattedValue) == "" {
if param.Required {
e.logger.Warn("必需参数为空",
zap.String("tool", toolName),
zap.String("param", param.Name),
)
return []string{}
}
continue
}
format := param.Format
if format == "" {
format = "flag" // 默认格式
@@ -418,23 +430,20 @@ func (e *Executor) buildCommandArgs(toolName string, toolConfig *config.ToolConf
if param.Flag != "" {
cmdArgs = append(cmdArgs, param.Flag)
}
formattedValue := e.formatParamValue(param, value)
if formattedValue != "" {
cmdArgs = append(cmdArgs, formattedValue)
}
cmdArgs = append(cmdArgs, formattedValue)
case "combined":
// --flag=value 或 -f=value
if param.Flag != "" {
cmdArgs = append(cmdArgs, fmt.Sprintf("%s=%s", param.Flag, e.formatParamValue(param, value)))
cmdArgs = append(cmdArgs, fmt.Sprintf("%s=%s", param.Flag, formattedValue))
} else {
cmdArgs = append(cmdArgs, e.formatParamValue(param, value))
cmdArgs = append(cmdArgs, formattedValue)
}
case "template":
// 使用模板字符串
if param.Template != "" {
template := param.Template
template = strings.ReplaceAll(template, "{flag}", param.Flag)
template = strings.ReplaceAll(template, "{value}", e.formatParamValue(param, value))
template = strings.ReplaceAll(template, "{value}", formattedValue)
template = strings.ReplaceAll(template, "{name}", param.Name)
cmdArgs = append(cmdArgs, strings.Fields(template)...)
} else {
@@ -442,14 +451,14 @@ func (e *Executor) buildCommandArgs(toolName string, toolConfig *config.ToolConf
if param.Flag != "" {
cmdArgs = append(cmdArgs, param.Flag)
}
cmdArgs = append(cmdArgs, e.formatParamValue(param, value))
cmdArgs = append(cmdArgs, formattedValue)
}
case "positional":
// 位置参数(已在上面处理)
cmdArgs = append(cmdArgs, e.formatParamValue(param, value))
cmdArgs = append(cmdArgs, formattedValue)
default:
// 默认:直接添加值
cmdArgs = append(cmdArgs, e.formatParamValue(param, value))
cmdArgs = append(cmdArgs, formattedValue)
}
}
+23 -6
View File
@@ -1,12 +1,29 @@
## Plugins
This directory contains optional plugins/extensions that integrate CyberStrikeAI with other tools.
Optional integrations that connect CyberStrikeAI with other tools.
- `burp-suite/`: Burp Suite extensions
### Burp Suite Extension
### Burp Suite
- **Path**: `plugins/burp-suite/cyberstrikeai-burp-extension/`
- **Build output**: `plugins/burp-suite/cyberstrikeai-burp-extension/dist/cyberstrikeai-burp-extension.jar`
- **Docs**: see the plugin folder `README.md` / `README.zh-CN.md`
- **Build**: `bash build-mvn.sh``dist/cyberstrikeai-burp-extension.jar`
- **Docs**: `README.md` / `README.zh-CN.md`
### Browser (Chrome / Edge)
- **Path**: `plugins/browser-extension/cyberstrikeai-browser-extension/`
- **Version**: **0.3.8**
- **Install**: `chrome://extensions/` → Load unpacked → F12 → **CyberStrikeAI** tab
- **Package**: `bash package.sh``dist/cyberstrikeai-browser-extension.zip`
- **Docs**: `README.zh-CN.md` (full) / `README.md` (summary)
#### Highlights (v0.3.x)
| Feature | Description |
|---------|-------------|
| Token expiry | Remaining time + 30s validate probe; detects server restart / unreachable |
| Capture pause | **● Capturing** / **○ Paused** — stop recording without closing DevTools |
| HTTP/1.1 display | Raw HAR in memory; UI + AI prompt normalized (no `:method` pseudo-headers) |
| Collapsible conn bar | Host/Port/Validate collapses after success |
| Popup | Read-only endpoint + connection status |
| Performance | XHR-only filter, no body read for static assets, rAF-throttled stream UI |
| Data caps | 200 captures/tab, 50 test runs, 512KB progress — all in-memory |
@@ -0,0 +1,72 @@
## CyberStrikeAI Browser Extension
**Version 0.3.8** — Full docs: **README.zh-CN.md**
Chromium DevTools extension: capture Network traffic and send it to CyberStrikeAI for AI-assisted security testing. Aligned with the Burp Suite plugin.
### Quick install
1. `chrome://extensions/` → Developer mode → **Load unpacked**
2. Select `plugins/browser-extension/cyberstrikeai-browser-extension/`
3. Open target page → **F12****CyberStrikeAI** tab → **Validate**
4. Select a captured request → **Send** → view **Output**
### Popup vs DevTools panel
| Location | Purpose |
|----------|---------|
| **DevTools panel** | Connection, Validate, capture, Send, Output (primary UI) |
| **Extension popup** | Read-only connection status + version + guide |
### Key features
- **Capture toggle**: **● Capturing** / **○ Paused** — pause stops `getContent` and list updates; Send still works on existing entries
- **Collapsible connection bar** — collapses to `https://host:port` after Validate
- **HTTP/1.1 normalization** — raw HAR stored; display and AI prompt strip HTTP/2 pseudo-headers (`:method`, etc.)
- **Test History** (50 runs) + **Captured Requests** (200/tab, XHR/Fetch filter)
- **SSE streaming** — Progress capped at 512KB; Final uncapped for active run
- **Deferred Markdown** — plain text while streaming; render after done; skip above 100KB
- **Stop** — abort local stream + server cancel via `conversationId`
- **Latest XHR**, **Copy**, project/role/agent send dialog
- Session token with **expires_at** tracking, 30s server probe, restart/unreachable detection
### Data limits (no unbounded growth)
| Data | Limit | Storage |
|------|-------|---------|
| Captures | 200 / tab | In-memory |
| Tabs tracked | 20 | In-memory |
| Test runs | 50 | Panel memory |
| Config / token | Small | `chrome.storage` |
Closing DevTools clears panel data. Closing the browser invalidates the session token.
### Performance
- **DevTools closed** → zero impact on page load
- **Capture paused** → near-zero overhead
- **Capturing + XHR only** → light overhead on matching requests only
### Troubleshooting
After reloading the extension, close DevTools completely and reopen (F12) if you see `chrome.runtime.connect` errors — the old panel context is invalidated.
### Package
```bash
bash package.sh
# → dist/cyberstrikeai-browser-extension.zip
```
### Layout
```text
manifest.json
background/service-worker.js
devtools.js
panel/ # main UI
popup/ # read-only status
lib/ # api, storage, capture, http-normalize, markdown, …
icons/
package.sh
```
@@ -0,0 +1,243 @@
## CyberStrikeAI 浏览器扩展
**当前版本:0.3.8**(UI 为英文;中文说明见下文)
Chrome / EdgeChromiumDevTools 扩展:在开发者工具中捕获 **Network** 流量,发送到 CyberStrikeAI 进行 AI 辅助安全测试。能力与 Burp Suite 插件对齐,并按生产场景做了性能与体验优化。
---
### 快速开始
1. `chrome://extensions/` → 开发者模式 → **加载已解压的扩展程序**
2. 选择目录:`plugins/browser-extension/cyberstrikeai-browser-extension/`
3. 打开目标页面 → **F12** → 顶部 Tab **CyberStrikeAI**
4. 填写 Host / Port / Password → **Validate**(首次会请求访问服务器地址权限)
5. 左侧选中捕获请求 → **Send** → 在 **Output** 查看 AI 结果
点击浏览器工具栏图标可查看 **只读连接状态**;完整配置与操作均在 DevTools 面板内完成。
---
### 界面说明
```
┌─ 连接栏(Validate 成功后可收起)────────────────────────────┐
│ Logo │ https://host:port │ 连接设置 │ ● OK │
├─ 操作栏 ────────────────────────────────────────────────────┤
│ Send │ Latest XHR │ Stop │ Copy │ Clear │ ●捕获中/○已暂停 │
│ XHR/Fetch only │ Debug │ Markdown │
├──────────────┬──────────────────────────────────────────────┤
│ Test History │ Output │ Request │ Response │
│ Captured Req │ Progress + Final Response │
└──────────────┴──────────────────────────────────────────────┘
```
| 区域 | 说明 |
|------|------|
| **连接栏** | Host、Port、HTTPS、Password、Validate;成功后收起为 `https://host:port` 摘要 |
| **Test History** | 最多 50 次 Send 记录,可回看 Progress / Final |
| **Captured Requests** | 当前 Tab 捕获列表,最多 200 条,支持搜索 |
| **Output** | 默认 Tab:流式 Progress + Final Response |
| **Request / Response** | 查看选中流量的 HTTP/1.1 格式原文 |
---
### 功能一览
#### 捕获
- **Background 中枢**`devtools.js` 监听 Network → `service-worker` 队列 → Panel 订阅
- 默认 **XHR/Fetch only**(可关闭以捕获更多类型)
- 静态资源 URL / MIME **预过滤**,命中前不读响应体
- **● 捕获中 / ○ 已暂停**:暂停后零开销,已有列表仍可 Send
- 单条截断:请求体 **64KB**、响应 **4KB**
#### HTTP 展示与 AI Prompt
- **存储**:内存中保留原始 HAR(含 HTTP/2 伪首部 `:method` 等)
- **展示 / Prompt**:归一化为 **HTTP/1.1**(与 Burp 插件一致)
```http
GET /api/foo HTTP/1.1
Host: example.com
Cookie: ...
```
#### 发送到 CyberStrikeAI
- 弹窗选择:**项目 / 角色 / 对话模式**(动态 API)+ 测试指令
- 支持 **Eino Single**、**Deep**、**Plan-Execute**、**Supervisor**
- **Latest XHR**:一键选中最近 API 请求并打开发送弹窗
- **Stop**:中止本地 SSE + 调用服务端 `/api/agent-loop/cancel`
#### 流式输出
- Progress 日志上限 **512KB**(超出截断)
- **Final Response 不截断**(当前进行中的测试)
- 历史 run 切换后 Final 软截断 **100KB**
- **Markdown**:流式阶段纯文本;结束后 `requestIdleCallback` 渲染;超 **100KB** 降级纯文本
- **Copy**:复制当前 Request / Response / Final
#### 安全与权限
- Token 存 **chrome.storage.session**(关浏览器失效)
- 登录后保存 **`expires_at`**,状态栏显示 **剩余时间**(如 `OK · 剩余 11h 30m`
- **不会自动续期**:过期后需重新 Validate(需 Password
- 本地过期检测(30s+ 服务端 `/api/auth/validate` 探测(同周期;切回面板时立即探测)
- 服务不可达时显示 **无法连接服务**;重启后 Token 失效显示 **服务已重启或 Token 已失效**
- **401/403** 时自动清空 Token 并展开连接栏
- Send 前主动校验 Token 有效性
- **optional_host_permissions**Validate 时按需授权
---
### 按钮与选项
| 控件 | 作用 |
|------|------|
| **Validate** | 登录并校验 Token;进行中再次点击为 Cancel |
| **连接设置 / 收起** | 展开或折叠 Host/Port/Password 表单 |
| **Send** | 对选中捕获发起到 CyberStrikeAI |
| **Latest XHR** | 选中最近 XHR/Fetch 并 Send |
| **Stop** | 停止当前 AI 流(本地 + 服务端) |
| **Clear Output** | 清空当前 run 的 Progress / Final |
| **● 捕获中 / ○ 已暂停** | 启用或暂停 Network 捕获 |
| **XHR/Fetch only** | 只捕获 API 类请求 |
| **Debug events** | 在 Progress 显示更多 SSE 事件 |
| **Markdown** | Final 完成后渲染富文本 |
| **Clear All** | 清空 Test History |
| **Clear** | 清空当前 Tab 捕获列表 |
---
### 数据与内存(不会无限增长)
| 数据 | 上限 | 位置 | 清理时机 |
|------|------|------|----------|
| 捕获请求 | 200 条 / Tab | Background + Panel 内存 | 超出丢弃最旧;可手动 Clear |
| Tab 捕获槽 | 20 个 Tab | Background 内存 | 超出丢弃非当前 Tab |
| 测试历史 | 50 条 | Panel 内存 | 超出丢弃最旧;Clear All |
| Progress | 512KB / run | Panel 内存 | 超出截断 |
| Final(进行中) | 无硬上限 | Panel 内存 | — |
| Final(历史) | 100KB 软截断 | Panel 内存 | 切换到其他 run 时 |
| 配置 + Token | 极小 | chrome.storage | 手动改配置 |
- 关闭 **DevTools** → Panel 内存清空
- 关闭 **浏览器** → Session Token 失效
- Service Worker 被回收 → Background 捕获队列清空
---
### 性能说明
| 场景 | 影响 |
|------|------|
| 未开 DevTools | **无影响**(不监听 Network |
| DevTools 开 + 捕获暂停 | **几乎无影响** |
| DevTools 开 + 捕获中 + XHR only | 仅匹配请求有轻微开销 |
| 高流量 SPA | 建议保持 **XHR/Fetch only**,不需要时点 **已暂停** |
已做优化:过滤器内存缓存、静态资源不读 body、列表增量插入、搜索防抖、rAF 节流流式 UI。
---
### 常见问题
**扩展更新后报错 `chrome.runtime.connect` undefined**
扩展重载后旧 DevTools 面板上下文失效。请:**关闭 DevTools → 重新加载扩展 → 再开 F12**。
**Token 过期会自动刷新吗?**
**不会自动续期**(无 refresh token)。插件会保存 `expires_at`、显示剩余时间;每 30s 向服务端校验,切回 DevTools 时立即校验。服务重启后 session 清空,会提示重新 Validate。
**重启服务后状态还显示 OK?**
v0.3.7 起每 30s 探测 `/api/auth/validate`;不可达显示黄色警告,Token 失效则清空并展开连接栏。重载扩展后请关闭 DevTools 再开 F12。
**Request 里为什么曾经有 `:authority``:method`**
HTTP/2 伪首部。展示与 AI Prompt 已归一化为 HTTP/1.1;原始 HAR 仍保存在内存 entry 中。
**Console 里 localhost CORS 报错是插件造成的吗?**
不是。那是页面自身请求本机服务被浏览器拦截,与扩展无关。
**Test History 很多会挡住 Captured Requests 吗?**
不会。历史区最高占侧边栏 **42%**,超出部分区域内滚动;捕获区占剩余空间。
**会拖慢网页吗?**
日常浏览(不开 DevTools)无影响。调试时可用 **已暂停** 完全停止捕获。
---
### Popup 与 DevTools 分工
| 位置 | 用途 |
|------|------|
| **DevTools 面板** | 连接、Validate、捕获、Send、Output(主工作区) |
| **扩展 Popup** | 只读连接状态 + 版本号 + 打开 DevTools 引导 |
不在 Popup 中重复完整配置表单,避免与主流程脱节。
---
### 打包发布
```bash
bash plugins/browser-extension/cyberstrikeai-browser-extension/package.sh
# → dist/cyberstrikeai-browser-extension.zip
```
图标从项目根 `images/logo.png` 生成:
```bash
LOGO="images/logo.png"
ICONS="plugins/browser-extension/cyberstrikeai-browser-extension/icons"
for size in 16 48 128; do
sips -z $size $size "$LOGO" --out "$ICONS/icon${size}.png"
done
```
---
### 限制
- Chrome **不提供** Network 面板右键菜单 API → 使用 **Latest XHR** + 自建列表
- Firefox 需 `about:debugging` 临时加载;`storage.session` 不可用时 Token 回退 `local`
- 无法一键从 Popup 跳转到 DevTools 指定面板(Chrome API 限制)
---
### 目录结构
```text
manifest.json # MV3 清单
background/service-worker.js # 捕获队列、Panel Port、全局开关
devtools.js # Network 监听(最早过滤)
devtools.html
panel/
panel.html / panel.js / panel.css # 主 UI
popup/
popup.html / popup.js / popup.css # 只读状态
lib/
auth-session.js # Token 过期检测与剩余时间提示
api.js # 登录、SSE、项目/角色 API
storage.js # 配置 + session token + expires_at
capture.js # HAR 摘要、静态过滤
http-normalize.js # HTTP/2 → HTTP/1.1 展示/Prompt
formatter.js # toPrompt 组装
markdown.js # Final Markdown 渲染
catalog-cache.js # 项目/角色 5 分钟缓存
constants.js # 上限常量
icons/ # 16 / 48 / 128
package.sh
```
---
### 与 Burp 插件对比
| 能力 | Burp 插件 | 浏览器扩展 |
|------|-----------|------------|
| 流量来源 | Proxy 历史 | DevTools Network |
| 连接配置 | Tab 内 | Tab 内(可折叠) |
| HTTP 格式 | HTTP/1.1 | 展示/Prompt 归一化为 HTTP/1.1 |
| 项目/角色/模式 | Send 弹窗 | Send 弹窗 |
| SSE 输出 | Progress + Final | Progress + Final |
| 捕获开关 | — | ● 捕获中 / ○ 已暂停 |
@@ -0,0 +1,143 @@
/* global chrome, CSAI_LIMITS, shouldCaptureEntry */
importScripts('../lib/constants.js', '../lib/capture.js');
/** Background hub: per-tab capture queue + panel subscriptions. */
const capturesByTab = new Map();
const portsByTab = new Map();
const filterApiByTab = new Map();
let captureEnabled = true;
function getCaptures(tabId) {
if (!capturesByTab.has(tabId)) capturesByTab.set(tabId, []);
return capturesByTab.get(tabId);
}
function trimCaptures(list) {
if (list.length > CSAI_LIMITS.MAX_CAPTURED) {
list.length = CSAI_LIMITS.MAX_CAPTURED;
}
}
function broadcastTab(tabId, message) {
const ports = portsByTab.get(tabId);
if (!ports) return;
for (const port of ports) {
try {
port.postMessage(message);
} catch (_) {
ports.delete(port);
}
}
}
function cleanupOldTabs(activeTabId) {
if (capturesByTab.size <= CSAI_LIMITS.MAX_TAB_CAPTURES) return;
for (const tabId of capturesByTab.keys()) {
if (tabId !== activeTabId) {
capturesByTab.delete(tabId);
portsByTab.delete(tabId);
filterApiByTab.delete(tabId);
}
if (capturesByTab.size <= CSAI_LIMITS.MAX_TAB_CAPTURES) break;
}
}
chrome.runtime.onConnect.addListener((port) => {
if (port.name !== 'cyberstrike-panel') return;
port.onDisconnect.addListener(() => {
for (const [tabId, set] of portsByTab.entries()) {
set.delete(port);
if (set.size === 0) portsByTab.delete(tabId);
}
});
port.onMessage.addListener((msg) => {
if (!msg || msg.type !== 'subscribe') return;
const tabId = msg.tabId;
if (tabId == null) return;
if (!portsByTab.has(tabId)) portsByTab.set(tabId, new Set());
portsByTab.get(tabId).add(port);
if (typeof msg.filterApiOnly === 'boolean') {
filterApiByTab.set(tabId, msg.filterApiOnly);
}
port.postMessage({ type: 'list', entries: getCaptures(tabId) });
cleanupOldTabs(tabId);
});
});
chrome.runtime.onMessage.addListener((msg, _sender, sendResponse) => {
if (!msg || !msg.type) return false;
if (msg.type === 'capture-entry') {
const tabId = msg.tabId;
if (tabId == null) return false;
if (!captureEnabled) {
sendResponse({ ok: true, skipped: true });
return false;
}
const filterApi = filterApiByTab.has(tabId) ? filterApiByTab.get(tabId) : true;
const entry = msg.entry;
if (!shouldCaptureEntry(entry, filterApi)) {
sendResponse({ ok: true, skipped: true });
return false;
}
const list = getCaptures(tabId);
list.unshift(entry);
trimCaptures(list);
broadcastTab(tabId, { type: 'entry', entry });
sendResponse({ ok: true });
return false;
}
if (msg.type === 'clear-captures') {
const tabId = msg.tabId;
if (tabId != null) {
capturesByTab.set(tabId, []);
broadcastTab(tabId, { type: 'list', entries: [] });
}
sendResponse({ ok: true });
return false;
}
if (msg.type === 'set-filter-api') {
const tabId = msg.tabId;
if (tabId != null && typeof msg.filterApiOnly === 'boolean') {
filterApiByTab.set(tabId, msg.filterApiOnly);
}
sendResponse({ ok: true });
return false;
}
if (msg.type === 'set-capture-enabled') {
if (typeof msg.enabled === 'boolean') {
captureEnabled = msg.enabled;
}
sendResponse({ ok: true });
return false;
}
if (msg.type === 'get-latest-api') {
const tabId = msg.tabId;
const list = getCaptures(tabId);
const latest = list.find((e) => {
const rt = (e.resourceType || '').toLowerCase();
return rt === 'xhr' || rt === 'fetch';
});
sendResponse({ entry: latest || null });
return false;
}
return false;
});
chrome.runtime.onInstalled.addListener(() => {
if (chrome.contextMenus && chrome.contextMenus.removeAll) {
chrome.contextMenus.removeAll();
}
});
@@ -0,0 +1,9 @@
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"></head>
<body>
<script src="lib/constants.js"></script>
<script src="lib/capture.js"></script>
<script src="devtools.js"></script>
</body>
</html>
@@ -0,0 +1,69 @@
/* global chrome, summarizeHarEntry, inferResourceType, mightCaptureRequest */
const FILTER_STORAGE_KEY = 'csai_filter_api_only';
const CAPTURE_ENABLED_KEY = 'csai_capture_enabled';
/** In-memory flags — avoids storage read on every network request. */
let filterApiOnly = true;
let captureEnabled = true;
function syncFromStorage(data) {
filterApiOnly = (data && data[FILTER_STORAGE_KEY]) !== false;
captureEnabled = (data && data[CAPTURE_ENABLED_KEY]) !== false;
}
chrome.storage.local.get([FILTER_STORAGE_KEY, CAPTURE_ENABLED_KEY], (data) => {
syncFromStorage(data);
});
chrome.storage.onChanged.addListener((changes, area) => {
if (area !== 'local') return;
if (changes[FILTER_STORAGE_KEY]) {
filterApiOnly = changes[FILTER_STORAGE_KEY].newValue !== false;
}
if (changes[CAPTURE_ENABLED_KEY]) {
captureEnabled = changes[CAPTURE_ENABLED_KEY].newValue !== false;
}
});
chrome.runtime.onMessage.addListener((msg) => {
if (!msg || !msg.type) return;
if (msg.type === 'set-filter-api' && typeof msg.filterApiOnly === 'boolean') {
filterApiOnly = msg.filterApiOnly;
}
if (msg.type === 'set-capture-enabled' && typeof msg.enabled === 'boolean') {
captureEnabled = msg.enabled;
}
});
chrome.devtools.network.onRequestFinished.addListener((request) => {
if (!captureEnabled) return;
const tabId = chrome.devtools.inspectedWindow.tabId;
const req = request.request || {};
const res = request.response || {};
const url = req.url || '';
const resourceType =
(request._resourceType || request.resourceType || inferResourceType(url, res.headers) || 'other')
.toLowerCase();
if (!mightCaptureRequest(url, resourceType, filterApiOnly)) {
return;
}
request.getContent((body) => {
const entry = summarizeHarEntry(request, body, resourceType);
chrome.runtime.sendMessage({
type: 'capture-entry',
tabId,
entry,
});
});
});
chrome.devtools.panels.create(
'CyberStrikeAI',
'icons/icon48.png',
'panel/panel.html',
() => {}
);
Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 633 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

@@ -0,0 +1,170 @@
const AGENT_MODES = [
{ id: 'eino_single', label: 'Eino Single (ADK)', path: '/api/eino-agent/stream' },
{ id: 'deep', label: 'Deep (DeepAgent)', path: '/api/multi-agent/stream', orchestration: 'deep' },
{ id: 'plan_execute', label: 'Plan-Execute', path: '/api/multi-agent/stream', orchestration: 'plan_execute' },
{ id: 'supervisor', label: 'Supervisor', path: '/api/multi-agent/stream', orchestration: 'supervisor' },
];
function agentModeById(id) {
return AGENT_MODES.find((m) => m.id === id) || AGENT_MODES[0];
}
async function apiFetch(baseUrl, path, options = {}) {
let res;
try {
res = await fetch(baseUrl + path, options);
} catch (err) {
const e = err instanceof Error ? err : new Error(String(err));
e.network = true;
throw e;
}
const text = await res.text();
let json = null;
try {
json = text ? JSON.parse(text) : null;
} catch (_) {
json = null;
}
if (!res.ok) {
const err = new Error((json && json.error) || text || `HTTP ${res.status}`);
err.status = res.status;
throw err;
}
return json;
}
async function loginAndValidate(baseUrl, password, signal) {
const login = await apiFetch(baseUrl, '/api/auth/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
body: JSON.stringify({ password }),
signal,
});
const token = login && login.token;
if (!token) throw new Error('Login response missing token');
await validateTokenSession(baseUrl, token, signal);
return {
token,
expiresAt: (login && login.expires_at) || '',
};
}
async function validateTokenSession(baseUrl, token, signal) {
await apiFetch(baseUrl, '/api/auth/validate', {
method: 'GET',
headers: { Authorization: `Bearer ${token}` },
signal,
});
}
async function fetchProjects(baseUrl, token, signal) {
const data = await apiFetch(baseUrl, '/api/projects?limit=500', {
headers: { Authorization: `Bearer ${token}` },
signal,
});
const list = (data && data.projects) || [];
const out = [{ id: '', label: '(none)' }];
for (const p of list) {
if (!p.id) continue;
let label = p.name || p.id;
if (p.status === 'archived') label += ' [archived]';
out.push({ id: p.id, label });
}
return out;
}
async function fetchRoles(baseUrl, token, signal) {
const data = await apiFetch(baseUrl, '/api/roles', {
headers: { Authorization: `Bearer ${token}` },
signal,
});
const list = (data && data.roles) || [];
const out = [{ id: '', label: 'Default' }];
for (const r of list) {
if (r.enabled === false) continue;
if (!r.name) continue;
out.push({ id: r.name, label: r.name });
}
return out;
}
function extractConversationId(ev) {
if (!ev || typeof ev !== 'object') return '';
if (ev.conversationId) return String(ev.conversationId).trim();
if (ev.data && ev.data.conversationId) return String(ev.data.conversationId).trim();
return '';
}
async function streamTest(baseUrl, token, options, handlers) {
const mode = agentModeById(options.agentMode);
const body = {
message: options.message,
conversationId: '',
role: options.role || '',
};
if (options.projectId) body.projectId = options.projectId;
if (mode.orchestration) body.orchestration = mode.orchestration;
const controller = new AbortController();
if (handlers.setAbortController) handlers.setAbortController(controller);
const res = await fetch(baseUrl + mode.path, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Accept: 'text/event-stream',
Authorization: `Bearer ${token}`,
},
body: JSON.stringify(body),
signal: controller.signal,
});
if (!res.ok) {
const t = await res.text();
const err = new Error(t || `HTTP ${res.status}`);
err.status = res.status;
throw err;
}
const reader = res.body.getReader();
const decoder = new TextDecoder();
let buffer = '';
while (true) {
const { done, value } = await reader.read();
if (done) break;
buffer += decoder.decode(value, { stream: true });
const lines = buffer.split('\n');
buffer = lines.pop() || '';
for (const line of lines) {
if (!line.startsWith('data:')) continue;
const json = line.slice(5).trim();
if (!json) continue;
let ev;
try {
ev = JSON.parse(json);
} catch (_) {
continue;
}
const type = ev.type || '';
const message = ev.message || '';
if (handlers.onEvent) handlers.onEvent(type, message, ev);
if (type === 'done') {
if (handlers.onDone) handlers.onDone();
return;
}
}
}
if (handlers.onDone) handlers.onDone();
}
async function cancelByConversationId(baseUrl, token, conversationId) {
await apiFetch(baseUrl, '/api/agent-loop/cancel', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${token}`,
},
body: JSON.stringify({ conversationId }),
});
}
@@ -0,0 +1,54 @@
/** Session token expiry helpers (aligned with web auth.js patterns). */
const SESSION_TOKEN_EXPIRY_KEY = 'csai_token_expires_at';
/** Warn when remaining session time is below this (ms). */
const TOKEN_WARN_BEFORE_MS = 30 * 60 * 1000;
function parseExpiresAt(iso) {
if (!iso) return null;
const d = new Date(iso);
return Number.isNaN(d.getTime()) ? null : d;
}
function isTokenExpiredByTime(expiresAtIso) {
const d = parseExpiresAt(expiresAtIso);
if (!d) return false;
return d.getTime() <= Date.now();
}
function tokenExpiresWithin(expiresAtIso, withinMs) {
const d = parseExpiresAt(expiresAtIso);
if (!d) return false;
return d.getTime() - Date.now() <= withinMs;
}
function formatTokenExpiryHint(expiresAtIso) {
const d = parseExpiresAt(expiresAtIso);
if (!d) return 'OK (token saved)';
const ms = d.getTime() - Date.now();
if (ms <= 0) return 'Session expired';
const h = Math.floor(ms / 3600000);
const m = Math.floor((ms % 3600000) / 60000);
if (h >= 1) return `OK · ${h}h ${m}m left`;
if (m >= 1) return `OK · ${m}m left`;
return 'OK · expiring soon';
}
function isAuthHttpStatus(status) {
return status === 401 || status === 403;
}
/** fetch() failed before HTTP response (server down, connection refused, etc.). */
function isNetworkFetchError(err) {
if (!err) return false;
if (err.network === true) return true;
if (err.name === 'AbortError') return false;
const msg = String(err.message || err);
return err.name === 'TypeError' && /fetch|network|Failed to fetch/i.test(msg);
}
function attachHttpStatus(err, status) {
if (err && typeof err === 'object') err.status = status;
return err;
}
@@ -0,0 +1,103 @@
/** Capture filtering and HAR entry normalization. */
const STATIC_EXT =
/\.(js|css|png|jpe?g|gif|svg|webp|ico|woff2?|ttf|eot|map|wasm)(\?|$)/i;
const STATIC_MIME_PREFIXES = [
'image/',
'font/',
'audio/',
'video/',
'text/css',
];
function inferResourceType(url, responseHeaders) {
if (STATIC_EXT.test(url || '')) return 'static';
const ct = headerValue(responseHeaders, 'content-type').toLowerCase();
for (const p of STATIC_MIME_PREFIXES) {
if (ct.startsWith(p)) return 'static';
}
return 'other';
}
function headerValue(headers, name) {
if (!headers || !headers.length) return '';
const lower = name.toLowerCase();
for (const h of headers) {
if ((h.name || '').toLowerCase() === lower) return h.value || '';
}
return '';
}
function headerLines(headers) {
if (!headers || !headers.length) return '';
return headers.map((h) => `${h.name}: ${h.value}`).join('\n');
}
function truncate(str, max) {
if (!str || str.length <= max) return str || '';
return str.slice(0, max) + '\n… [truncated]';
}
function shouldCaptureEntry(entry, filterApiOnly) {
if (!entry || !entry.url) return false;
return mightCaptureRequest(entry.url, entry.resourceType, filterApiOnly);
}
/** Fast pre-filter before reading response body in devtools. */
function mightCaptureRequest(url, resourceType, filterApiOnly) {
const rt = (resourceType || inferResourceType(url, null) || 'other').toLowerCase();
if (filterApiOnly) {
return rt === 'xhr' || rt === 'fetch' || rt === 'websocket';
}
if (rt === 'static') return false;
if (STATIC_EXT.test(url || '')) return false;
return true;
}
function summarizeHarEntry(harEntry, responseBody, resourceType) {
const req = harEntry.request || {};
const res = harEntry.response || {};
const url = req.url || '';
let path = '/';
try {
const u = new URL(url);
path = u.pathname + (u.search || '');
} catch (_) {
path = url;
}
const shortPath = path.length > 80 ? path.slice(0, 77) + '...' : path;
const title = `${req.method || 'GET'} ${shortPath}`;
return {
id: `${Date.now()}_${Math.random().toString(36).slice(2, 8)}`,
title,
method: req.method || 'GET',
url,
resourceType: resourceType || 'other',
requestHeaders: headerLines(req.headers),
requestBody: truncate((req.postData && req.postData.text) || '', CSAI_LIMITS.MAX_REQUEST_BODY),
responseStatus: res.status,
responseHeaders: headerLines(res.headers),
responseBody: truncate(responseBody || '', CSAI_LIMITS.MAX_RESPONSE_BODY),
capturedAt: Date.now(),
};
}
function summarizePageContext(page) {
return {
id: `page_${Date.now()}`,
title: `PAGE ${page.title || page.url || ''}`.slice(0, 80),
method: 'PAGE',
url: page.url || '',
resourceType: 'document',
requestHeaders: '',
requestBody: '',
responseStatus: 0,
responseHeaders: '',
responseBody: '',
pageTitle: page.title || '',
isPageContext: true,
capturedAt: Date.now(),
};
}
@@ -0,0 +1,39 @@
/** In-memory cache for projects / roles lists (per baseUrl + token). */
const CATALOG_CACHE_TTL_MS = 5 * 60 * 1000;
const catalogCache = {
baseUrl: '',
token: '',
projects: null,
roles: null,
fetchedAt: 0,
};
function catalogCacheValid(baseUrl, token) {
if (!catalogCache.fetchedAt) return false;
if (catalogCache.baseUrl !== baseUrl || catalogCache.token !== token) return false;
return Date.now() - catalogCache.fetchedAt < CATALOG_CACHE_TTL_MS;
}
function invalidateCatalogCache() {
catalogCache.projects = null;
catalogCache.roles = null;
catalogCache.fetchedAt = 0;
}
async function fetchCatalogCached(baseUrl, token, signal) {
if (catalogCacheValid(baseUrl, token) && catalogCache.projects && catalogCache.roles) {
return { projects: catalogCache.projects, roles: catalogCache.roles };
}
const [projects, roles] = await Promise.all([
fetchProjects(baseUrl, token, signal),
fetchRoles(baseUrl, token, signal),
]);
catalogCache.baseUrl = baseUrl;
catalogCache.token = token;
catalogCache.projects = projects;
catalogCache.roles = roles;
catalogCache.fetchedAt = Date.now();
return { projects, roles };
}
@@ -0,0 +1,17 @@
/** Shared limits and defaults for the browser extension. */
const CSAI_LIMITS = {
MAX_CAPTURED: 200,
MAX_RUNS: 50,
MAX_REQUEST_BODY: 65536,
MAX_RESPONSE_BODY: 4096,
/** Progress log only; active Final Response is not truncated. */
MAX_PROGRESS_CHARS: 524288,
MAX_TAB_CAPTURES: 20,
/** Markdown render skipped above this size (plain text only). */
MAX_MARKDOWN_CHARS: 100000,
/** Non-selected completed runs: soft-trim final to limit memory. */
MAX_FINAL_ARCHIVE_CHARS: 100000,
};
const CSAI_DEFAULT_INSTRUCTION =
'Perform web penetration testing on this traffic and output results. Test only this endpoint; do not expand to other APIs.';
@@ -0,0 +1,47 @@
const DEFAULT_INSTRUCTION = CSAI_DEFAULT_INSTRUCTION;
function defaultInstruction() {
return DEFAULT_INSTRUCTION;
}
function toPrompt(entry, instruction) {
if (entry && entry.isPageContext) {
const prefix = (instruction && instruction.trim()) ? instruction.trim() : DEFAULT_INSTRUCTION;
return (
prefix +
'\n\n[Target]\n' +
'PAGE ' +
(entry.url || '') +
'\n\n[Page]\n' +
'Title: ' +
(entry.pageTitle || '') +
'\nURL: ' +
(entry.url || '')
);
}
const prefix = (instruction && instruction.trim()) ? instruction.trim() : DEFAULT_INSTRUCTION;
const method = entry.method || 'GET';
const url = entry.url || '(unknown)';
const reqHeaders = normalizeRequestBlock(entry);
const reqBody = entry.requestBody || '';
let respSnippet = '';
if (entry.responseHeaders || entry.responseBody) {
respSnippet =
'\n\n[Optional: Response (truncated)]\n' +
normalizeResponseBlock(entry) +
'\n\n' +
(entry.responseBody || '');
}
return (
prefix +
'\n\n[Target]\n' +
method +
' ' +
url +
'\n\n[Request]\n' +
reqHeaders +
'\n\n' +
reqBody +
respSnippet
);
}
@@ -0,0 +1,104 @@
/** HTTP/2 pseudo-header HTTP/1.1 normalization for display and AI prompts.
* Raw HAR headers in storage are never modified. */
function parseHeaderLines(headerText) {
const headers = [];
for (const line of String(headerText || '').split(/\r?\n/)) {
if (!line.trim()) continue;
const idx = line.indexOf(':');
if (idx <= 0) continue;
headers.push({
name: line.slice(0, idx).trim(),
value: line.slice(idx + 1).trim(),
});
}
return headers;
}
function urlParts(url) {
try {
const u = new URL(url || '');
return {
host: u.host,
path: (u.pathname || '/') + (u.search || ''),
};
} catch (_) {
return { host: '', path: '/' };
}
}
/** Request line + headers (HTTP/1.1), no body. */
function normalizeRequestBlock(entry) {
if (!entry || entry.isPageContext) return entry?.requestHeaders || '';
const headers = parseHeaderLines(entry.requestHeaders);
const fromUrl = urlParts(entry.url);
let method = entry.method || 'GET';
let path = fromUrl.path || '/';
let host = fromUrl.host;
const regular = [];
let hasHost = false;
for (const h of headers) {
const name = h.name;
const lower = name.toLowerCase();
if (name.startsWith(':')) {
if (lower === ':method') method = h.value || method;
else if (lower === ':path') path = h.value || path;
else if (lower === ':authority') host = h.value || host;
continue;
}
if (lower === 'host') hasHost = true;
regular.push(`${name}: ${h.value}`);
}
if (host && !hasHost) {
regular.unshift(`Host: ${host}`);
}
if (!path.startsWith('/')) path = '/' + path;
return `${method} ${path} HTTP/1.1\n${regular.join('\n')}`;
}
/** Status line + headers (HTTP/1.1), no body. */
function normalizeResponseBlock(entry) {
if (!entry) return '';
const headers = parseHeaderLines(entry.responseHeaders);
let status = entry.responseStatus || 0;
const regular = [];
for (const h of headers) {
const name = h.name;
const lower = name.toLowerCase();
if (name.startsWith(':')) {
if (lower === ':status') {
const n = parseInt(h.value, 10);
if (!Number.isNaN(n)) status = n;
}
continue;
}
regular.push(`${name}: ${h.value}`);
}
const statusLine = `HTTP/1.1 ${status || '?'}`;
return regular.length ? `${statusLine}\n${regular.join('\n')}` : statusLine;
}
function formatRequestDisplay(entry) {
if (!entry) return '';
if (entry.isPageContext) {
return `PAGE ${entry.url || ''}\n\nTitle: ${entry.pageTitle || ''}`;
}
const block = normalizeRequestBlock(entry);
const body = entry.requestBody || '';
return body ? `${block}\n\n${body}` : block;
}
function formatResponseDisplay(entry) {
if (!entry) return '';
const block = normalizeResponseBlock(entry);
const body = entry.responseBody || '';
return body ? `${block}\n\n${body}` : block;
}
@@ -0,0 +1,135 @@
/** Minimal Markdown → HTML (aligned with Burp plugin renderer). */
function mdEscapeHtml(s) {
return String(s || '')
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;');
}
function mdHeadingLevel(s) {
let i = 0;
while (i < s.length && s[i] === '#') i++;
if (i >= 1 && i <= 6 && i < s.length && /\s/.test(s[i])) return i;
return 0;
}
function mdReplaceInlineCode(s) {
let out = '';
let inCode = false;
let buf = '';
for (let i = 0; i < s.length; i++) {
const c = s[i];
if (c === '`') {
if (!inCode) {
inCode = true;
buf = '';
} else {
out += `<code>${buf}</code>`;
inCode = false;
}
continue;
}
if (inCode) buf += c;
else out += c;
}
if (inCode) out += '`' + buf;
return out;
}
function mdReplaceBold(s) {
let out = '';
let i = 0;
while (i < s.length) {
const start = s.indexOf('**', i);
if (start < 0) {
out += s.slice(i);
break;
}
const end = s.indexOf('**', start + 2);
if (end < 0) {
out += s.slice(i);
break;
}
out += s.slice(i, start) + '<b>' + s.slice(start + 2, end) + '</b>';
i = end + 2;
}
return out;
}
function mdInlineFormat(text) {
let escaped = mdEscapeHtml(text);
escaped = mdReplaceInlineCode(escaped);
escaped = mdReplaceBold(escaped);
return escaped;
}
function markdownToHtml(markdown) {
const lines = String(markdown || '').split(/\r?\n/);
const css =
'body{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;font-size:13px;line-height:1.45;margin:10px;color:#111;}' +
'code,pre{font-family:ui-monospace,Menlo,Consolas,monospace;}' +
'code{font-size:0.95em;background:#f6f8fa;border:1px solid #e5e7eb;border-radius:4px;padding:0 4px;}' +
'pre{font-size:0.95em;background:#f6f8fa;border:1px solid #e5e7eb;border-radius:6px;padding:10px;overflow:auto;}' +
'pre code{background:transparent;border:none;padding:0;}' +
'p{margin:0.55em 0;}ul{margin:0.4em 0 0.6em 1.2em;padding:0;}';
let out = `<html><head><meta charset="utf-8"><style>${css}</style></head><body>`;
let inCode = false;
let inList = false;
let codeBuf = '';
for (const raw of lines) {
const line = raw == null ? '' : raw;
if (line.trim().startsWith('```')) {
if (!inCode) {
inCode = true;
codeBuf = '';
} else {
out += `<pre><code>${mdEscapeHtml(codeBuf)}</code></pre>`;
inCode = false;
}
continue;
}
if (inCode) {
codeBuf += line + '\n';
continue;
}
const trimmed = line.trim();
if (!trimmed) {
if (inList) {
out += '</ul>';
inList = false;
}
out += "<div style='height:6px'></div>";
continue;
}
const h = mdHeadingLevel(trimmed);
if (h > 0) {
if (inList) {
out += '</ul>';
inList = false;
}
out += `<h${h}>${mdInlineFormat(trimmed.slice(h).trim())}</h${h}>`;
continue;
}
if (trimmed.startsWith('- ') || trimmed.startsWith('* ')) {
if (!inList) {
out += '<ul>';
inList = true;
}
out += `<li>${mdInlineFormat(trimmed.slice(2).trim())}</li>`;
continue;
}
if (inList) {
out += '</ul>';
inList = false;
}
out += `<p>${mdInlineFormat(trimmed)}</p>`;
}
if (inCode) out += `<pre><code>${mdEscapeHtml(codeBuf)}</code></pre>`;
if (inList) out += '</ul>';
out += '</body></html>';
return out;
}

Some files were not shown because too many files have changed in this diff Show More