Files
ja4-platform/services/bot-detector/IMPROVEMENTS.md
Jacquin Antoine 7894d39f1c feat(ml): replace logistic regression with MLP fusion and KS drift with ADWIN online learning
Replace the LogisticRegression meta-learner with a PyTorch MetaFusionMLP
(Linear(3,16)->BN->ReLU->Dropout->Linear(16,1)->Sigmoid) for non-linear
fusion of EIF, NF, and XGBoost scores. Replace KS-test + quantile digest
drift detection with ADWIN (adaptive sliding window, Hoeffding bound).
Replace weekly XGBoost batch retraining with River HoeffdingAdaptiveTree
for incremental online learning (learn_one per cycle). Update all thesis
documentation sections (2.4.2c, 2.4.3, 3.8, discussion, conclusion).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 16:32:34 +02:00

26 KiB
Raw Blame History

Bot Detector IA — Axes d'amélioration

Suivi d'implémentation — mis à jour le 2026-04-13 | Architecture modulaire (16 modules)


Résumé des axes proposés — État d'implémentation

# Axe Statut Implémentation
A1 Détection de dérive conceptuelle IMPLÉMENTÉ scoring.py : _compute_drift_score() + fallback z-score
A2 Seuil adaptatif par percentile IMPLÉMENTÉ scoring.py : compute_adaptive_threshold()
A3 Analyse multi-fenêtres temporelles IMPLÉMENTÉ cycle.py : ENABLE_MULTIWINDOW + Complet_24h/Applicatif_24h
A4 Explainabilité par SHAP IMPLÉMENTÉ scoring.py : _compute_shap_top_features(), top-5
A5 Déduplication avec TTL inter-cycles IMPLÉMENTÉ cycle.py : _filter_recent_detections(), DEDUP_TTL_MIN=60
A6 Pondération par récurrence dans le score IMPLÉMENTÉ pipeline.py : raw -= log1p(count) * RECURRENCE_WEIGHT
A7 Validation de complétude des features IMPLÉMENTÉ scoring.py : validate_features(), MIN_VALID_FEATURE_RATIO=0.50
A8 Clustering comportemental des anomalies IMPLÉMENTÉ scoring.py : HDBSCAN + escalade campagne dans pipeline.py
A9 Métriques Prometheus / health check enrichi À FAIRE Health check binaire uniquement (infra.py : 200/503)
A10 Normalisation des scores entre modèles IMPLÉMENTÉ scoring.py : normalize_scores() min-max [0, 1]

A1 — Détection de dérive conceptuelle

IMPLÉMENTÉ (ADWIN)

Module : scoring.py — classe ADWINDriftMonitor (remplace _compute_drift_score)

Différences avec la proposition initiale :

Proposition Implémentation
KS-test + quantile digest ADWIN (fenêtre glissante adaptative, borne de Hoeffding)
Seuil par p_value < 0.05 Borne de Hoeffding automatique (delta = 0.002)
DRIFT_THRESHOLD (30%) Identique : DRIFT_THRESHOLD = 0.30 (fraction de features en dérive)
Sauvegarde dans .meta.json ADWIN stateful — pas de sauvegarde nécessaire (fenêtre adaptative)
Événement DRIFT_DETECTED Journalisé avec la liste des features dérivées

Appelé depuis : models.pyload_or_train_model(), avant la décision de chargement vs retrain.

Problème

L'Isolation Forest est entraîné sur la baseline humaine courante. Si le profil du trafic légitime évolue graduellement (nouveau navigateur populaire, changement de comportement utilisateur, migration réseau), le modèle vieilli peut :

  • Générer des faux positifs sur du trafic humain nouvellement apparu
  • Rater des faux négatifs si les bots imitent les anciens patterns

Références

  • Gama et al. (2014) — A Survey on Concept Drift Adaptation
  • Rabanser et al. (2019) — Failing Loudly: An Empirical Study of Methods for Detecting Dataset Shift

A2 — Seuil adaptatif par percentile

IMPLÉMENTÉ

Module : scoring.py — fonction compute_adaptive_threshold()

Implémentation conforme à la proposition :

neg_scores = scores[scores < 0]
adaptive = np.percentile(neg_scores, ANOMALY_PERCENTILE)   # défaut : 5
effective_threshold = min(adaptive, ANOMALY_THRESHOLD)      # garde-fou : -0.05
Proposition Implémentation
ANOMALY_PERCENTILE (020, défaut 5) config.py : ANOMALY_PERCENTILE = 5
Seuil statique en garde-fou ANOMALY_THRESHOLD = -0.05
Log du seuil effectif dans ANOMALY Journalisé dans les événements

Appelé depuis : pipeline.py ligne 144, sur les scores bruts EIF uniquement.


A3 — Analyse multi-fenêtres temporelles

IMPLÉMENTÉ

Module : cycle.py — dans fetch_and_analyze(), lignes 257275

Implémentation :

Proposition Implémentation
Vue 24h dans ClickHouse MULTIWINDOW_VIEW = 'view_ai_features_24h' (configurable)
Deux modèles supplémentaires Complet_24h et Applicatif_24h
Combinaison AND logique Implémenté en OR logique : une IP est flaggée si anomalie dans ≥ 1 fenêtre
Score le plus bas conservé En cas de doublon, le score le plus bas (le plus anormal) est conservé
Activation par feature flag ENABLE_MULTIWINDOW = false par défaut

Note : La proposition originale suggérait un AND logique (anomalie dans les deux fenêtres). L'implémentation utilise un OR pour maximiser la couverture, avec déduplication par score minimal.


A4 — Explainabilité par SHAP

IMPLÉMENTÉ

Module : scoring.py — fonction _compute_shap_top_features()

Proposition Implémentation
TreeExplainer (sklearn IF) Pour sklearn : shap.TreeExplainer
Top-5 features les plus contributives Top-5 features avec valeurs SHAP
ENABLE_SHAP=true/false config.py : ENABLE_SHAP = true (ET SHAP_AVAILABLE)
SHAP uniquement sur les anomalies Calculé uniquement pour les IPs flaggées
Enrichissement du champ reason Via _build_reason() — SHAP intégré dans la raison textuelle

Ajout par rapport à la proposition : Pour isotree (Extended IF), SHAP utilise PermutationExplainer au lieu de TreeExplainer (isotree n'est pas nativement supporté par TreeSHAP).

Appelé depuis : pipeline.py lignes 298303, après l'extraction des anomalies.

Références

  • Lundberg & Lee (2017) — A Unified Approach to Interpreting Model Predictions

A5 — Déduplication avec TTL inter-cycles

IMPLÉMENTÉ

Module : cycle.py — fonction _filter_recent_detections()

Proposition Implémentation
DEDUP_TTL_MIN (défaut 60 min) config.py : DEDUP_TTL_MIN = 60
Requête ClickHouse pour les IPs récentes Interroge ml_detected_anomalies dans les dernières DEDUP_TTL_MIN minutes
Variante : réinsertion si dégradation ≥ 0.05 Réinsertion uniquement si le score s'est dégradé de ≥ 0.05 points
DEDUP_TTL_MIN=0 pour désactiver Conforme
Déduplication intra-cycle (drop_duplicates) cycle.py ligne 302 : drop_duplicates(subset=['src_ip'], keep='first')

A6 — Pondération par récurrence dans le score

IMPLÉMENTÉ

Module : pipeline.py — lignes 148151

Proposition Implémentation
RECURRENCE_WEIGHT = 0.005 config.py : RECURRENCE_WEIGHT = 0.005
adjusted = score - log1p(recurrence) * weight raw_anomaly_score -= log1p(recurrence_count) * RECURRENCE_WEIGHT
Récurrence chargée depuis ClickHouse view_ip_recurrence dans cycle.py ligne 215
Stockage séparé raw_score / adjusted_score Le score ajusté remplace raw_anomaly_score (pas de stockage séparé)

A7 — Validation de complétude des features

IMPLÉMENTÉ

Module : scoring.py — fonction validate_features()

Proposition Implémentation
Détection des features absentes Features manquantes du DataFrame
Détection des features constantes (std=0) Features à std=0 exclues
MIN_VALID_FEATURE_RATIO (défaut 0.8) Implémenté à 0.50 (seuil moins strict)
Événement FEATURE_WARNING Journalisé dans le JSONL
SKIPPED_INVALID_FEATURES si ratio insuffisant Retourne None → cycle ignoré

Ajouts par rapport à la proposition :

  • Détection des features entièrement à zéro (pipeline non alimenté) en plus des features constantes.
  • Exclusions structurelles par modèle (STRUCTURAL_EXCLUDED_FEATURES dans config.py) : le modèle Applicatif exclut automatiquement 15 features TCP/TLS non disponibles sans corrélation.

A8 — Clustering comportemental des anomalies

IMPLÉMENTÉ

Module : scoring.py — fonction _cluster_anomalies() + pipeline.py pour l'escalade

Proposition Implémentation
DBSCAN (eps=0.5, min_samples=3) Utilisé en fallback. Algorithme principal : HDBSCAN
campaign_id dans les événements Journalisé dans les événements ANOMALY et inséré dans ml_detected_anomalies
eps et min_samples configurables CLUSTERING_MIN_SAMPLES = 3, ENABLE_CLUSTERING = true
Activation conditionnelle ENABLE_CLUSTERING (feature flag)

Améliorations par rapport à la proposition :

  1. HDBSCAN au lieu de DBSCAN : Utilise HDBSCAN(min_cluster_size=3, min_samples=2, cluster_selection_method='eom') via import optionnel hdbscan. Fallback DBSCAN si hdbscan non installé.

  2. Clustering dans l'espace latent : Si un modèle Autoencoder est disponible, le clustering opère dans l'espace latent (dimension 16) plutôt que sur les features brutes — meilleure séparation des clusters.

  3. Escalade de campagne (pipeline.py lignes 311324) : Les IPs d'un cluster ≥ 5 membres voient leur threat level escaladé de HIGHCRITICAL.

Références

  • Ester et al. (1996) — A Density-Based Algorithm for Discovering Clusters in Large Spatial Databases
  • Campello et al. (2013) — Density-Based Clustering Based on Hierarchical Density Estimates (HDBSCAN)

A9 — Métriques Prometheus / health check enrichi

À FAIRE

État actuel : Le health check est un serveur HTTP binaire dans infra.py (200 OK / 503 DEGRADED). Aucun endpoint /metrics n'est exposé.

Ce qui manque :

  • Endpoint /metrics au format Prometheus text
  • Métriques : durée du cycle, nombre d'anomalies par modèle, âge du modèle, taille de la baseline, score de dérive
  • Intégration Grafana/Alertmanager

Prérequis : Ajouter prometheus_client aux dépendances ou implémenter le format texte manuellement sur le HTTPServer existant.

Note : La priorité est faible car les métriques clés sont déjà disponibles via les événements CYCLE_END dans le JSONL et les tables ClickHouse (ml_all_scores).

Proposition originale

Exposer un endpoint /metrics sur le même port que le health check :

botdetector_cycle_duration_seconds 12.4
botdetector_anomalies_total{model="Complet"} 3
botdetector_model_age_hours{model="Applicatif"} 0.91
botdetector_human_baseline_size{model="Applicatif"} 1725

A10 — Normalisation des scores entre modèles

IMPLÉMENTÉ

Module : scoring.py — fonction normalize_scores()

Proposition Implémentation
Min-max sur les scores < 0 Normalisation min-max des scores négatifs
Intervalle [-1, 0] Intervalle [0, 1] où 1 = le plus anormal
Threat levels sur score normalisé Les threat levels sont toujours calculés sur le score brut IF (score_to_threat_level() dans infra.py)
Déduplication sur score normalisé La déduplication utilise le score brut ajusté (avec pénalité de récurrence)

Note : Le choix de conserver les threat levels sur le score brut (plutôt que normalisé) assure la stabilité des seuils de classification. Le score normalisé est utilisé pour le score final combiné (EIF+AE+XGB) et l'insertion dans ml_all_scores.


Notes d'implémentation générales

  • Compatibilité : toute amélioration doit rester rétrocompatible avec le schéma ml_detected_anomalies existant (ajout de colonnes optionnelles uniquement)
  • Architecture modulaire : le code est réparti en 16 modules (voir DOCUMENTATION.md §1.1), chaque amélioration touche un ou deux modules spécifiques
  • Tests : 36 tests auto-contenus dans tests/test_detector.py, exécutables via make test-bot-detector
  • Feature flags : les fonctionnalités sont activables via variables d'environnement (ENABLE_SHAP, ENABLE_CLUSTERING, ENABLE_MULTIWINDOW, ENABLE_FEEDBACK)
  • Imports optionnels : isotree, torch, xgboost, shap, hdbscan sont tous optionnels avec fallbacks (config.py)

Nouvelles dimensions de features — Propositions B

Propositions de features supplémentaires pour l'ensemble ML, validées sur les données réelles de ja4_processing. Chaque proposition indique la force du signal observée en base, la source de données, la formule de calcul et les références scientifiques.

Résumé des signaux — État d'implémentation

# Feature Statut Modèle Implémentation
B1 ja3_diversity_ratio IMPLÉMENTÉ Complet FEATURES_COMPLET dans preprocessing.py ligne 56
B2 syn_timing_cv IMPLÉMENTÉ Complet FEATURES_COMPLET dans preprocessing.py ligne 56
B3 tls12_ratio IMPLÉMENTÉ Complet FEATURES_COMPLET dans preprocessing.py ligne 56
B4 head_ratio IMPLÉMENTÉ Les deux FEATURES dans preprocessing.py ligne 30
B5 sec_fetch_absence_rate IMPLÉMENTÉ Les deux FEATURES dans preprocessing.py ligne 30
B6 generic_accept_ratio IMPLÉMENTÉ Les deux FEATURES dans preprocessing.py ligne 30
B7 http10_ratio IMPLÉMENTÉ Les deux FEATURES dans preprocessing.py ligne 30
B8 ip_df_variance IMPLÉMENTÉ Complet FEATURES_COMPLET dans preprocessing.py ligne 56
B9 IP DF-bit consistency 🔄 PARTIEL Complet Couvert par B8 (ip_df_variance), pas de feature séparée
B10 JA4 concentration intra-ASN IMPLÉMENTÉ (préexistant) Les deux ja4_asn_concentration dans FEATURES — existait avant les propositions B

B1 — JA3/JA4 Diversity Ratio (rotation de fingerprint TLS)

IMPLÉMENTÉ

Feature : ja3_diversity_ratio — dans FEATURES_COMPLET (modèle Complet uniquement).

Exclusion structurelle : Exclue du modèle Applicatif via STRUCTURAL_EXCLUDED_FEATURES dans config.py, car le JA3 n'est disponible que pour le trafic corrélé (L4/TLS).

Détails d'implémentation :

  • La vue ClickHouse view_ai_features_1h calcule uniqMerge(uniq_ja3) / greatest(uniq_ja4, 1)
  • Le MV mv_agg_host_ip_ja4_1h agrège uniqState(ja3) depuis http_logs

Observation originale

185.177.72.60  →  1619 JA3 distincts  /  2 JA4  →  ratio 809.5
194.187.171.160 →  153 JA3 distincts  /  2 JA4  →  ratio 76.5

Le JA4 reste stable (il encode le type de client TLS + ALPN) mais le JA3 varie massivement. C'est la signature d'un bot qui randomise les extensions TLS pour contourner la détection par fingerprint.

Références

  • Siby et al. (2020) — Encrypted DNS → Privacy? A Traffic Analysis Perspective
  • Anderson & McGrew (2016) — Machine Learning for Encrypted Malware Traffic Classification
  • Husák et al. (2022) — TLS fingerprinting for bot detection

B2 — SYN-to-ClientHello Timing Regularity

IMPLÉMENTÉ

Feature : syn_timing_cv — dans FEATURES_COMPLET (modèle Complet uniquement).

Implémentation : Coefficient de variation (std/mean) du timing SYN→ClientHello, calculé dans la vue ClickHouse : sqrt(tcp_jitter_variance) / greatest(avg_syn_ms, 1).

Observation originale

88.202.237.59 : 45 connexions, avg=22ms, std=0.00ms  → timing robotique parfait
386/3222 IPs analysées (12%) ont une variance=0

Références

  • Zeber et al. (2020) — The Measurement of Web Timing
  • Stevanovic & Pedersen (2015) — Detecting Bots Using Multi-level Traffic Analysis

B3 — TLS 1.2 Exclusive Ratio

IMPLÉMENTÉ

Feature : tls12_ratio — dans FEATURES_COMPLET (modèle Complet uniquement).

Utilisation double : En plus d'être une feature ML, tls12_ratio est utilisée par l'axe 5 (TLS/TCP Coherence) de la détection navigateur dans browser.py (condition tls12_ratio < 0.1 pour un score positif).

Observation originale

95.217.144.244 : 360/360 requêtes en TLS 1.2 (jamais TLS 1.3)
136 IPs utilisent exclusivement TLS 1.2 sur 3259 analysées (4.2%)

Références

  • Kotzias et al. (2018) — Coming of Age: A Longitudinal Study of TLS Deployment
  • Cloudflare Radar 2024 — TLS 1.3 = 95%+ du trafic web mondial

B4 — HEAD Method Ratio

IMPLÉMENTÉ

Feature : head_ratio — dans FEATURES (les deux modèles).

Commentaire dans le code : # B4-B7 : features L7 pures (preprocessing.py ligne 29).

Observation originale

34.140.199.84 : 11/12 requêtes HEAD (91.7%) → Google Cloud uptime checker
67/3335 IPs ont >50% de requêtes HEAD

Références

  • Barracuda Networks (2023) — Bot Traffic Report
  • OWASP Automated Threat Handbook — OAT-011: Scraping, OAT-018: Credential Stuffing

B5 — Sec-Fetch Absence Rate

IMPLÉMENTÉ

Feature : sec_fetch_absence_rate — dans FEATURES (les deux modèles).

Utilisation double : Également utilisée par l'axe 3 (HTTP Modern) de la détection navigateur dans browser.py (condition sec_fetch_absence_rate < 0.3 pour un score positif, poids 0.25).

Observation originale

Les headers Sec-Fetch-* sont injectés automatiquement par les navigateurs modernes (Chrome 76+, Firefox 90+). Leur absence signale un client non-navigateur.

Références

  • West & Loshbough (2019) — Fetch Metadata Request Headers (W3C Spec)
  • Invernizzi et al. (2016) — CLOAK of Visibility

B6 — Accept Header Entropy

IMPLÉMENTÉ

Feature : generic_accept_ratio — dans FEATURES (les deux modèles).

Note : La proposition originale suggérait une entropie du header Accept. L'implémentation utilise l'approche simplifiée (fraction de requêtes avec Accept générique/vide), qui est plus robuste et moins coûteuse en calcul ClickHouse.

Utilisation double : Également utilisée par l'axe 3 (HTTP Modern) dans browser.py (condition generic_accept_ratio < 0.3, poids 0.10).

Références

  • Nikiforakis et al. (2013) — Cookieless Monster
  • Acar et al. (2014) — The Web Never Forgets

B7 — HTTP/TLS Protocol Version Mismatch

IMPLÉMENTÉ

Feature : http10_ratio — dans FEATURES (les deux modèles).

Note : La proposition originale contenait deux features (http1_tls13_ratio et http10_ratio). Seule http10_ratio (fraction de requêtes HTTP/1.0) a été implémentée — c'est le signal le plus fort car HTTP/1.0 est extrêmement rare dans le trafic navigateur moderne.

Utilisation double : Également utilisée par l'axe 5 (TLS/TCP Coherence) dans browser.py (condition http10_ratio = 0, poids 0.15).


B8 — IP DF-Bit Consistency

IMPLÉMENTÉ

Feature : ip_df_variance — dans FEATURES_COMPLET (modèle Complet uniquement).

Implémentation : varPop(toFloat64(ip_meta_df)) dans la vue ClickHouse. La variance du bit DF est combinée avec les features TTL (avg_ttl, ttl_std) pour le TCP fingerprinting multi-dimensionnel.


B9 — IP DF-Bit Consistency (proposition distincte)

🔄 PARTIEL

État : Couvert par B8. La proposition B9 était une variante de B8 avec une analyse de cohérence intra-session supplémentaire. Cette variante n'a pas été implémentée séparément — ip_df_variance couvre le cas d'usage principal.


B10 — JA4 Concentration intra-ASN

IMPLÉMENTÉ (préexistant)

Feature : ja4_asn_concentration — dans FEATURES (les deux modèles).

Note : Cette feature existait déjà avant les propositions B, dans la liste initiale des features du modèle. Elle mesure la concentration d'un même fingerprint JA4 au sein d'un ASN — un JA4 très concentré dans un seul ASN suggère un outil déployé dans un datacenter spécifique.


Récapitulatif des modifications ClickHouse réalisées

Colonnes ajoutées dans agg_host_ip_ja4_1h

Les colonnes suivantes ont été ajoutées au MV et à la table d'agrégation pour supporter les features B1B8 :

-- B1 : JA3 diversity ratio
uniq_ja3              AggregateFunction(uniq, String)
-- B2 : SYN timing regularity
avg_syn_ms            SimpleAggregateFunction(avg, Float64)
-- B3 : TLS 1.2 ratio
tls12_count           SimpleAggregateFunction(sum, UInt64)
-- B4 : HEAD method ratio
count_head            SimpleAggregateFunction(sum, UInt64)
-- B5 : Sec-Fetch absence
count_no_sec_fetch    SimpleAggregateFunction(sum, UInt64)
-- B6 : Generic Accept ratio
count_generic_accept  SimpleAggregateFunction(sum, UInt64)
-- B7 : HTTP/1.0 ratio
count_http10          SimpleAggregateFunction(sum, UInt64)
-- B8 : DF-bit variance
ip_df_variance        (calculé via varPop dans la vue)

Features dérivées dans view_ai_features_1h

Feature Formule Modèle
ja3_diversity_ratio uniqMerge(uniq_ja3) / greatest(uniq_ja4, 1) Complet
syn_timing_cv sqrt(tcp_jitter_variance) / greatest(avg_syn_ms, 1) Complet
tls12_ratio tls12_count / greatest(hits, 1) Complet
head_ratio count_head / greatest(hits, 1) Les deux
sec_fetch_absence_rate count_no_sec_fetch / greatest(hits, 1) Les deux
generic_accept_ratio count_generic_accept / greatest(hits, 1) Les deux
http10_ratio count_http10 / greatest(hits, 1) Les deux
ip_df_variance varPop(toFloat64(ip_meta_df)) Complet

Fonctionnalités ajoutées hors propositions initiales

Features et mécanismes implémentés dans la refonte modulaire qui ne figuraient pas dans les propositions A1A10 / B1B10 originales.

Ensemble triple-voix (EIF + Autoencoder + XGBoost)

Module : models.py

La proposition initiale n'incluait qu'un Isolation Forest. L'architecture actuelle utilise un ensemble triple-voix :

Modèle Poids Rôle
Extended Isolation Forest (isotree) 56% Détection non supervisée principale
Autoencoder (PyTorch) 24% Erreur de reconstruction comme signal complémentaire
XGBoost 20% Supervision via feedback SOC (soc_feedback)

Formule de combinaison :

final = (1 - β) × [(1 - α) × eif_norm + α × ae_norm] + β × xgb_prob

α = AE_WEIGHT = 0.30 et β = XGB_WEIGHT = 0.20.

Extended Isolation Forest (isotree)

Module : models.py

Remplacement de sklearn IsolationForest par isotree.ExtendedIsolationForest :

  • ndim=min(3, len(features)) — partitions multi-dimensionnelles (contre 1D pour sklearn)
  • Calibration des scores : sklearn_equiv = 0.5 - isotree_score
  • Fallback automatique vers sklearn si isotree non installé

Détection multifactorielle des navigateurs (5 axes)

Module : browser.py

Nouveau système de classification des navigateurs légitimes basé sur 5 axes pondérés indépendants (voir DOCUMENTATION.md §3.4) :

Axe Poids Signal
1 — JA4 Known 0.25 Famille navigateur identifiée
2 — JA4 Structure 0.15 TLS 1.3, h2/h3, ciphers/extensions
3 — HTTP Modern 0.25 Sec-Fetch, Accept-Language, modern_browser_score
4 — Nav Behavior 0.15 Cookies, Referer, assets, navigation
5 — TLS Coherence 0.20 ALPN, window scale, TLS 1.2 ratio

Seuil : browser_confidence ≥ 0.55 + famille identifiée → LEGITIMATE_BROWSER.

Escalade de campagne

Module : pipeline.py lignes 311324

Après le clustering HDBSCAN, les IPs appartenant à un cluster de ≥ 5 membres voient leur threat level escaladé de HIGHCRITICAL. Identifie les campagnes de botnet coordonnées.

Feedback SOC (apprentissage supervisé)

Module : cycle.py lignes 221238

Intégration du feedback des analystes SOC depuis la table audit_logs :

  • Faux positifs (FP) → reclassés en baseline humaine (asn_label='isp')
  • Vrais positifs (TP) → étiquetés soc_confirmed_bot pour l'entraînement XGBoost
  • Configurable via ENABLE_FEEDBACK=true et FEEDBACK_WINDOW_DAYS=7

Features thèse §5

Module : preprocessing.py + cycle.py

9 features issues de la thèse (§5) enrichies depuis view_thesis_features_1h :

  • seq_emb_0..seq_emb_31 — embeddings séquentiels via SessionTransformer (§5.2, remplace path_transition_entropy + cadence_cv)
  • burst_ratio / pause_ratio — ratios de rafales et pauses
  • lag1_autocorrelation — autocorrélation lag-1 des inter-arrivées
  • benford_deviation — déviation par rapport à la loi de Benford
  • host_diversity / host_sweep_speed / host_coverage_uniformity

Features P0+P1 (sous-exploitées et nouvelles)

Module : preprocessing.py

Features supplémentaires ajoutées à FEATURES :

  • is_fake_navigation — détection de fausse navigation (P0)
  • true_window_size / window_mss_ratio — TCP window analysis (P0, Complet)
  • has_xff — présence de X-Forwarded-For (P1)
  • unusual_content_type_ratio — Content-Types inhabituels (P1)
  • non_standard_port_ratio — ports non standard (P1)
  • login_post_concentration — concentration de POST sur login (P1)
  • sec_ch_mobile_mismatch — incohérence Sec-CH-UA-Mobile (P1)

TTL Fingerprinting OS

Module : preprocessing.pyFEATURES_COMPLET

Features TCP ajoutées pour le fingerprinting du système d'exploitation :

  • avg_ttl — TTL moyen (différent par OS : 64 Linux, 128 Windows, 255 Cisco)
  • ttl_std — écart-type du TTL (doit être ~0 pour un trafic homogène)
  • no_window_scale_ratio — ratio de sessions sans TCP window scaling

Dérive JA4 intra-session

Module : preprocessing.pyFEATURES_COMPLET

  • ja4_drift_ratio — fraction de sessions où le JA4 change pendant la session. Signal de bot qui reconfigure son client TLS à chaque requête.

Validation gate (modèles)

Module : models.py

Après entraînement, le modèle est validé sur un jeu de validation (split 80/20). Si val_anomaly_rate > 0.20, le modèle est rejeté et l'ancien modèle est conservé. Empêche le déploiement de modèles dégénérés.

Feature pruning automatique

Module : models.py

Les features avec variance < 1e-6 sont automatiquement éliminées avant l'entraînement de l'EIF. Évite les partitions dégénérées sur des features constantes.