🛡️ 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>
93 lines
2.8 KiB
Python
93 lines
2.8 KiB
Python
"""
|
|
Endpoints pour la liste des attributs uniques
|
|
"""
|
|
from fastapi import APIRouter, HTTPException, Query
|
|
from ..database import db
|
|
from ..models import AttributeListResponse, AttributeListItem
|
|
|
|
router = APIRouter(prefix="/api/attributes", tags=["attributes"])
|
|
|
|
|
|
@router.get("/{attr_type}", response_model=AttributeListResponse)
|
|
async def get_attributes(
|
|
attr_type: str,
|
|
limit: int = Query(100, ge=1, le=1000, description="Nombre maximum de résultats")
|
|
):
|
|
"""
|
|
Récupère la liste des valeurs uniques pour un type d'attribut
|
|
"""
|
|
try:
|
|
# Mapping des types vers les colonnes
|
|
type_column_map = {
|
|
"ip": "src_ip",
|
|
"ja4": "ja4",
|
|
"country": "country_code",
|
|
"asn": "asn_number",
|
|
"host": "host",
|
|
"threat_level": "threat_level",
|
|
"model_name": "model_name",
|
|
"asn_org": "asn_org"
|
|
}
|
|
|
|
if attr_type not in type_column_map:
|
|
raise HTTPException(
|
|
status_code=400,
|
|
detail=f"Type invalide. Types supportés: {', '.join(type_column_map.keys())}"
|
|
)
|
|
|
|
column = type_column_map[attr_type]
|
|
|
|
# Requête de base
|
|
base_query = f"""
|
|
SELECT
|
|
{column} AS value,
|
|
count() AS count
|
|
FROM ml_detected_anomalies
|
|
WHERE detected_at >= now() - INTERVAL 24 HOUR
|
|
"""
|
|
|
|
# Ajout du filtre pour exclure les valeurs vides/nulles
|
|
# Gestion spéciale pour les types IPv6/IPv4 qui ne peuvent pas être comparés à ''
|
|
if attr_type == "ip":
|
|
# Pour les adresses IP, on convertit en string et on filtre
|
|
query = f"""
|
|
SELECT value, count FROM (
|
|
SELECT toString({column}) AS value, count() AS count
|
|
FROM ml_detected_anomalies
|
|
WHERE detected_at >= now() - INTERVAL 24 HOUR
|
|
GROUP BY {column}
|
|
)
|
|
WHERE value != '' AND value IS NOT NULL
|
|
ORDER BY count DESC
|
|
LIMIT %(limit)s
|
|
"""
|
|
else:
|
|
query = f"""
|
|
{base_query}
|
|
AND {column} != '' AND {column} IS NOT NULL
|
|
GROUP BY value
|
|
ORDER BY count DESC
|
|
LIMIT %(limit)s
|
|
"""
|
|
|
|
result = db.query(query, {"limit": limit})
|
|
|
|
items = [
|
|
AttributeListItem(
|
|
value=str(row[0]),
|
|
count=row[1]
|
|
)
|
|
for row in result.result_rows
|
|
]
|
|
|
|
return AttributeListResponse(
|
|
type=attr_type,
|
|
items=items,
|
|
total=len(items)
|
|
)
|
|
|
|
except HTTPException:
|
|
raise
|
|
except Exception as e:
|
|
raise HTTPException(status_code=500, detail=f"Erreur: {str(e)}")
|