Add a complete AI pentest system where Claude autonomously drives security testing via tool-calling. The LLM selects from 16 tools, chains results, and builds an attack chain DAG. Core: - PentestTool trait (dyn-compatible) with PentestToolContext/Result - PentestSession, AttackChainNode, PentestMessage, PentestEvent models - 10 new DastVulnType variants (DNS, DMARC, TLS, cookies, CSP, CORS, etc.) - LLM client chat_with_tools() for OpenAI-compatible tool calling Tools (16 total): - 5 agent wrappers: SQL injection, XSS, auth bypass, SSRF, API fuzzer - 11 new infra tools: DNS checker, DMARC checker, TLS analyzer, security headers, cookie analyzer, CSP analyzer, rate limit tester, console log detector, CORS checker, OpenAPI parser, recon - ToolRegistry for tool lookup and LLM definition generation Orchestrator: - PentestOrchestrator with iterative tool-calling loop (max 50 rounds) - Attack chain node recording per tool invocation - SSE event broadcasting for real-time progress - Strategy-aware system prompts (quick/comprehensive/targeted/aggressive/stealth) API (9 endpoints): - POST/GET /pentest/sessions, GET /pentest/sessions/:id - POST /pentest/sessions/:id/chat, GET /pentest/sessions/:id/stream - GET /pentest/sessions/:id/attack-chain, messages, findings - GET /pentest/stats Dashboard: - Pentest dashboard with stat cards, severity distribution, session list - Chat-based session page with split layout (chat + findings/attack chain) - Inline tool execution indicators, auto-polling, new session modal - Sidebar navigation item Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
68 lines
2.1 KiB
Rust
68 lines
2.1 KiB
Rust
use dioxus::prelude::*;
|
|
|
|
use crate::components::app_shell::AppShell;
|
|
use crate::pages::*;
|
|
|
|
#[derive(Debug, Clone, Routable, PartialEq)]
|
|
#[rustfmt::skip]
|
|
#[allow(clippy::enum_variant_names)]
|
|
pub enum Route {
|
|
#[layout(AppShell)]
|
|
#[route("/")]
|
|
OverviewPage {},
|
|
#[route("/repositories")]
|
|
RepositoriesPage {},
|
|
#[route("/findings")]
|
|
FindingsPage {},
|
|
#[route("/findings/:id")]
|
|
FindingDetailPage { id: String },
|
|
#[route("/sbom")]
|
|
SbomPage {},
|
|
#[route("/issues")]
|
|
IssuesPage {},
|
|
#[route("/graph")]
|
|
GraphIndexPage {},
|
|
#[route("/graph/:repo_id")]
|
|
GraphExplorerPage { repo_id: String },
|
|
#[route("/graph/:repo_id/impact/:finding_id")]
|
|
ImpactAnalysisPage { repo_id: String, finding_id: String },
|
|
#[route("/chat")]
|
|
ChatIndexPage {},
|
|
#[route("/chat/:repo_id")]
|
|
ChatPage { repo_id: String },
|
|
#[route("/dast")]
|
|
DastOverviewPage {},
|
|
#[route("/dast/targets")]
|
|
DastTargetsPage {},
|
|
#[route("/dast/findings")]
|
|
DastFindingsPage {},
|
|
#[route("/dast/findings/:id")]
|
|
DastFindingDetailPage { id: String },
|
|
#[route("/pentest")]
|
|
PentestDashboardPage {},
|
|
#[route("/pentest/:session_id")]
|
|
PentestSessionPage { session_id: String },
|
|
#[route("/mcp-servers")]
|
|
McpServersPage {},
|
|
#[route("/settings")]
|
|
SettingsPage {},
|
|
}
|
|
|
|
const FAVICON: Asset = asset!("/assets/favicon.svg");
|
|
const MAIN_CSS: Asset = asset!("/assets/main.css");
|
|
const TAILWIND_CSS: Asset = asset!("/assets/tailwind.css");
|
|
const VIS_NETWORK_JS: Asset = asset!("/assets/vis-network.min.js");
|
|
const GRAPH_VIZ_JS: Asset = asset!("/assets/graph-viz.js");
|
|
|
|
#[component]
|
|
pub fn App() -> Element {
|
|
rsx! {
|
|
document::Link { rel: "icon", href: FAVICON }
|
|
document::Link { rel: "stylesheet", href: TAILWIND_CSS }
|
|
document::Link { rel: "stylesheet", href: MAIN_CSS }
|
|
document::Script { src: VIS_NETWORK_JS }
|
|
document::Script { src: GRAPH_VIZ_JS }
|
|
Router::<Route> {}
|
|
}
|
|
}
|