mirror of
https://github.com/CyberSecurityUP/NeuroSploit.git
synced 2026-05-26 16:17:49 +02:00
NeuroSploit v3.2.4 - MD Agent Orchestrator Overhaul + Claude 4.6 + SmartRouter Failover
- MD Agent system restructured: real HTTP exploitation, retry with exponential backoff, reduced concurrency (2 parallel, 2s stagger) - Claude 4.6 model support (Opus/Sonnet) with corrected API version headers - SmartRouter true failover with provider preference cascade - WAFResult attribute error fix in autonomous_agent.py - CVSS data sanitization for all vulnerability database saves - AI recon JSON parsing robustness improvements - rebuild.sh simplified from 714 to 196 lines - Frontend: removed unused routes, simplified Auto Pentest page - Agent grid: reduced max tests per agent (8→5), condensed recon prompts Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
+32
-11
@@ -18,6 +18,27 @@ from datetime import datetime
|
||||
from enum import Enum
|
||||
from urllib.parse import urlparse
|
||||
|
||||
|
||||
def _safe_cvss_score(val) -> float:
|
||||
"""Sanitize cvss_score: convert to float, default 0.0 for non-numeric."""
|
||||
if val is None:
|
||||
return 0.0
|
||||
if isinstance(val, (int, float)):
|
||||
return float(val)
|
||||
try:
|
||||
return float(val)
|
||||
except (ValueError, TypeError):
|
||||
return 0.0
|
||||
|
||||
|
||||
def _safe_cvss_vector(val) -> str:
|
||||
"""Sanitize cvss_vector: return empty string for N/A or invalid values."""
|
||||
if not val or not isinstance(val, str):
|
||||
return ""
|
||||
if val.strip().upper().startswith("N/A") or len(val.strip()) < 5:
|
||||
return ""
|
||||
return val[:100]
|
||||
|
||||
from backend.core.autonomous_agent import AutonomousAgent, OperationMode
|
||||
from backend.core.task_library import get_task_library
|
||||
from backend.db.database import async_session_factory
|
||||
@@ -123,7 +144,7 @@ class AgentRequest(BaseModel):
|
||||
enable_kali_sandbox: bool = Field(False, description="Enable Kali Linux sandbox for tool execution + AI researcher")
|
||||
custom_prompt_ids: Optional[List[str]] = Field(None, description="IDs of custom prompts to include in agent flow")
|
||||
preferred_provider: Optional[str] = Field(None, description="Preferred LLM provider (e.g., 'anthropic', 'gemini_cli', 'openai')")
|
||||
preferred_model: Optional[str] = Field(None, description="Preferred model name (e.g., 'claude-sonnet-4-20250514', 'gemini-2.0-flash')")
|
||||
preferred_model: Optional[str] = Field(None, description="Preferred model name (e.g., 'claude-sonnet-4-6-20250918', 'claude-opus-4-6-20250918', 'gemini-2.0-flash')")
|
||||
methodology_file: Optional[str] = Field(None, description="Path to external .md methodology file to inject into all AI calls")
|
||||
enable_cli_agent: bool = Field(False, description="Enable CLI Agent (AI CLI inside Kali sandbox)")
|
||||
cli_agent_provider: Optional[str] = Field(None, description="CLI provider: claude_code, gemini_cli, codex_cli")
|
||||
@@ -431,8 +452,8 @@ async def _run_agent_task(
|
||||
title=finding.get("title", finding.get("type", "Unknown")),
|
||||
vulnerability_type=finding.get("vulnerability_type", finding.get("type", "unknown")),
|
||||
severity=severity,
|
||||
cvss_score=finding.get("cvss_score"),
|
||||
cvss_vector=finding.get("cvss_vector"),
|
||||
cvss_score=_safe_cvss_score(finding.get("cvss_score")),
|
||||
cvss_vector=_safe_cvss_vector(finding.get("cvss_vector")),
|
||||
cwe_id=finding.get("cwe_id"),
|
||||
description=finding.get("description") or finding.get("evidence") or "",
|
||||
affected_endpoint=finding.get("affected_endpoint", finding.get("endpoint", finding.get("url", target))),
|
||||
@@ -463,8 +484,8 @@ async def _run_agent_task(
|
||||
title=finding.get("title", finding.get("type", "Unknown")),
|
||||
vulnerability_type=finding.get("vulnerability_type", finding.get("type", "unknown")),
|
||||
severity=finding.get("severity", "medium").lower(),
|
||||
cvss_score=finding.get("cvss_score"),
|
||||
cvss_vector=finding.get("cvss_vector"),
|
||||
cvss_score=_safe_cvss_score(finding.get("cvss_score")),
|
||||
cvss_vector=_safe_cvss_vector(finding.get("cvss_vector")),
|
||||
cwe_id=finding.get("cwe_id"),
|
||||
description=finding.get("description") or finding.get("evidence") or "",
|
||||
affected_endpoint=finding.get("affected_endpoint", finding.get("endpoint", finding.get("url", target))),
|
||||
@@ -916,8 +937,8 @@ async def stop_agent(agent_id: str):
|
||||
title=finding.get("title", finding.get("type", "Unknown")),
|
||||
vulnerability_type=finding.get("vulnerability_type", finding.get("type", "unknown")),
|
||||
severity=severity,
|
||||
cvss_score=finding.get("cvss_score"),
|
||||
cvss_vector=finding.get("cvss_vector"),
|
||||
cvss_score=_safe_cvss_score(finding.get("cvss_score")),
|
||||
cvss_vector=_safe_cvss_vector(finding.get("cvss_vector")),
|
||||
cwe_id=finding.get("cwe_id"),
|
||||
description=finding.get("description") or finding.get("evidence") or "",
|
||||
affected_endpoint=finding.get("affected_endpoint", finding.get("endpoint", finding.get("url", target))),
|
||||
@@ -949,8 +970,8 @@ async def stop_agent(agent_id: str):
|
||||
title=finding.get("title", finding.get("type", "Unknown")),
|
||||
vulnerability_type=finding.get("vulnerability_type", finding.get("type", "unknown")),
|
||||
severity=finding.get("severity", "medium").lower(),
|
||||
cvss_score=finding.get("cvss_score"),
|
||||
cvss_vector=finding.get("cvss_vector"),
|
||||
cvss_score=_safe_cvss_score(finding.get("cvss_score")),
|
||||
cvss_vector=_safe_cvss_vector(finding.get("cvss_vector")),
|
||||
cwe_id=finding.get("cwe_id"),
|
||||
description=finding.get("description") or finding.get("evidence") or "",
|
||||
affected_endpoint=finding.get("affected_endpoint", finding.get("endpoint", finding.get("url", target))),
|
||||
@@ -2493,8 +2514,8 @@ async def _save_realtime_findings_to_db(session_id: str, session: Dict):
|
||||
title=title,
|
||||
vulnerability_type=finding.get("vulnerability_type", "unknown"),
|
||||
severity=severity,
|
||||
cvss_score=finding.get("cvss_score"),
|
||||
cvss_vector=finding.get("cvss_vector"),
|
||||
cvss_score=_safe_cvss_score(finding.get("cvss_score")),
|
||||
cvss_vector=_safe_cvss_vector(finding.get("cvss_vector")),
|
||||
cwe_id=finding.get("cwe_id"),
|
||||
description=finding.get("description") or finding.get("evidence") or "",
|
||||
affected_endpoint=finding.get("affected_endpoint", target),
|
||||
|
||||
@@ -155,6 +155,7 @@ async def test_connection(provider_id: str, account_id: str):
|
||||
PROVIDER_MODELS = {
|
||||
"claude_code": [
|
||||
"claude-opus-4-6-20250918",
|
||||
"claude-sonnet-4-6-20250918",
|
||||
"claude-sonnet-4-5-20250929",
|
||||
"claude-haiku-4-5-20251001",
|
||||
"claude-sonnet-4-20250514",
|
||||
@@ -163,6 +164,7 @@ PROVIDER_MODELS = {
|
||||
],
|
||||
"kiro": [
|
||||
"claude-opus-4-6-20250918",
|
||||
"claude-sonnet-4-6-20250918",
|
||||
"claude-sonnet-4-5-20250929",
|
||||
"claude-haiku-4-5-20251001",
|
||||
"claude-sonnet-4-20250514",
|
||||
@@ -171,6 +173,7 @@ PROVIDER_MODELS = {
|
||||
],
|
||||
"anthropic": [
|
||||
"claude-opus-4-6-20250918",
|
||||
"claude-sonnet-4-6-20250918",
|
||||
"claude-sonnet-4-5-20250929",
|
||||
"claude-haiku-4-5-20251001",
|
||||
"claude-sonnet-4-20250514",
|
||||
@@ -214,17 +217,18 @@ PROVIDER_MODELS = {
|
||||
"cursor-fast",
|
||||
"cursor-small",
|
||||
"gpt-4o",
|
||||
"claude-sonnet-4-6-20250918",
|
||||
"claude-sonnet-4-5-20250929",
|
||||
"claude-3-5-sonnet-20241022",
|
||||
],
|
||||
"copilot": [
|
||||
"gpt-4o",
|
||||
"gpt-4o-mini",
|
||||
"claude-sonnet-4-6-20250918",
|
||||
"claude-sonnet-4-5-20250929",
|
||||
"claude-3-5-sonnet-20241022",
|
||||
],
|
||||
"openrouter": [
|
||||
"anthropic/claude-opus-4-6",
|
||||
"anthropic/claude-sonnet-4-6",
|
||||
"anthropic/claude-sonnet-4-5",
|
||||
"anthropic/claude-haiku-4-5",
|
||||
"anthropic/claude-sonnet-4",
|
||||
|
||||
@@ -533,9 +533,12 @@ MODEL_CACHE_TTL = 60 # seconds
|
||||
# Common cloud models for dropdown suggestions
|
||||
CLOUD_MODELS = {
|
||||
"claude": [
|
||||
{"model_id": "claude-opus-4-6-20250918", "display_name": "Claude Opus 4.6", "context_length": 1000000},
|
||||
{"model_id": "claude-sonnet-4-6-20250918", "display_name": "Claude Sonnet 4.6", "context_length": 1000000},
|
||||
{"model_id": "claude-sonnet-4-5-20250929", "display_name": "Claude Sonnet 4.5", "context_length": 200000},
|
||||
{"model_id": "claude-haiku-4-5-20251001", "display_name": "Claude Haiku 4.5", "context_length": 200000},
|
||||
{"model_id": "claude-sonnet-4-20250514", "display_name": "Claude Sonnet 4", "context_length": 200000},
|
||||
{"model_id": "claude-opus-4-20250514", "display_name": "Claude Opus 4", "context_length": 200000},
|
||||
{"model_id": "claude-haiku-4-20250514", "display_name": "Claude Haiku 4", "context_length": 200000},
|
||||
],
|
||||
"openai": [
|
||||
{"model_id": "gpt-4o", "display_name": "GPT-4o", "context_length": 128000},
|
||||
|
||||
Reference in New Issue
Block a user