Initial commit: Bot Detector Dashboard for SOC Incident Response

🛡️ Dashboard complet pour l'analyse et la classification des menaces

Fonctionnalités principales:
- Visualisation des détections en temps réel (24h)
- Investigation multi-entités (IP, JA4, ASN, Host, User-Agent)
- Analyse de corrélation pour classification SOC
- Clustering automatique par subnet/JA4/UA
- Export des classifications pour ML

Composants:
- Backend: FastAPI (Python) + ClickHouse
- Frontend: React + TypeScript + TailwindCSS
- 6 routes API: metrics, detections, variability, attributes, analysis, entities
- 7 types d'entités investigables

Documentation ajoutée:
- NAVIGATION_GRAPH.md: Graph complet de navigation
- SOC_OPTIMIZATION_PROPOSAL.md: Proposition d'optimisation pour SOC
  • Réduction de 7 à 2 clics pour classification
  • Nouvelle vue /incidents clusterisée
  • Panel latéral d'investigation
  • Quick Search (Cmd+K)
  • Timeline interactive
  • Graph de corrélations

Sécurité:
- .gitignore configuré (exclut .env, secrets, node_modules)
- Credentials dans .env (à ne pas committer)

⚠️ Audit sécurité réalisé - Voir recommandations dans SOC_OPTIMIZATION_PROPOSAL.md

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
SOC Analyst
2026-03-14 21:33:55 +01:00
commit a61828d1e7
55 changed files with 11189 additions and 0 deletions

View File

@ -0,0 +1,48 @@
import { useState, useEffect } from 'react';
import { detectionsApi, DetectionsListResponse } from '../api/client';
interface UseDetectionsParams {
page?: number;
page_size?: number;
threat_level?: string;
model_name?: string;
country_code?: string;
asn_number?: string;
search?: string;
sort_by?: string;
sort_order?: string;
}
export function useDetections(params: UseDetectionsParams = {}) {
const [data, setData] = useState<DetectionsListResponse | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<Error | null>(null);
useEffect(() => {
const fetchDetections = async () => {
setLoading(true);
try {
const response = await detectionsApi.getDetections(params);
setData(response.data);
} catch (err) {
setError(err instanceof Error ? err : new Error('Erreur inconnue'));
} finally {
setLoading(false);
}
};
fetchDetections();
}, [
params.page,
params.page_size,
params.threat_level,
params.model_name,
params.country_code,
params.asn_number,
params.search,
params.sort_by,
params.sort_order,
]);
return { data, loading, error };
}

View File

@ -0,0 +1,29 @@
import { useState, useEffect } from 'react';
import { metricsApi, MetricsResponse } from '../api/client';
export function useMetrics() {
const [data, setData] = useState<MetricsResponse | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<Error | null>(null);
useEffect(() => {
const fetchMetrics = async () => {
try {
const response = await metricsApi.getMetrics();
setData(response.data);
} catch (err) {
setError(err instanceof Error ? err : new Error('Erreur inconnue'));
} finally {
setLoading(false);
}
};
fetchMetrics();
// Rafraîchissement automatique toutes les 30 secondes
const interval = setInterval(fetchMetrics, 30000);
return () => clearInterval(interval);
}, []);
return { data, loading, error };
}

View File

@ -0,0 +1,30 @@
import { useState, useEffect } from 'react';
import { variabilityApi, VariabilityResponse } from '../api/client';
export function useVariability(type: string, value: string) {
const [data, setData] = useState<VariabilityResponse | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<Error | null>(null);
useEffect(() => {
if (!type || !value) {
setLoading(false);
return;
}
const fetchVariability = async () => {
try {
const response = await variabilityApi.getVariability(type, value);
setData(response.data);
} catch (err) {
setError(err instanceof Error ? err : new Error('Erreur inconnue'));
} finally {
setLoading(false);
}
};
fetchVariability();
}, [type, value]);
return { data, loading, error };
}