Files
ja4-platform/docs/thesis/02_etat_de_lart.md
Jacquin Antoine 0e5f94dd0d docs: restructure thesis into chapter files with corrected references
Split monolithic thesis into separate chapter markdown files under
docs/thesis/. Remove fabricated bibliography entries, correct inflated
claims, add GNN/Transformers section, and rename MetaLearner to Fusion LR.

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

58 KiB
Raw Blame History

<< Sommaire | Suivant >>


2. État de l'art

2.1 Détection par règles statiques

2.1.1 OWASP Core Rule Set (CRS)

L'OWASP Core Rule Set (CRS) est un ensemble de règles génériques de détection d'attaques pour les pare-feux applicatifs web (WAF — Web Application Firewall) compatibles ModSecurity et Coraza. La version 4.0, publiée en février 2024, couvre les catégories d'attaques suivantes :

SQLi (SQL Injection) : injection de code SQL malveillant dans des paramètres de requête ou formulaires pour manipuler les requêtes de base de données. Exemple : ' OR '1'='1 dans un champ de connexion pour contourner l'authentification.

XSS (Cross-Site Scripting) : injection de code JavaScript dans des pages web dynamiques pour qu'il s'exécute dans le navigateur d'autres utilisateurs. Exemple : <script>document.cookie</script> dans un commentaire.

LFI/RFI (Local File Inclusion / Remote File Inclusion) : exploitation de fonctions d'inclusion de fichiers pour charger des fichiers arbitraires depuis le système local (LFI : ../../etc/passwd) ou depuis un serveur distant (RFI : http://attacker.com/shell.php).

RCE (Remote Code Execution) : exécution de commandes système arbitraires sur le serveur via une vulnérabilité applicative. Particulièrement destructeur car il donne à l'attaquant le contrôle complet de l'hôte.

Scanners connus : signatures de Nikto, Nessus, OpenVAS, sqlmap, Nuclei — outils de reconnaissance et de fuzzing dont les User-Agents et patterns de requêtes sont documentés.

Points forts du CRS :

Propriété Valeur
Déterminisme Totalement déterministe, explicable
Latence < 1 ms par requête
Couverture OWASP Top 10, CWE courants
Maintenance Communauté active, mises à jour fréquentes
Intégration ModSecurity, Coraza, Nginx, Apache, F5

Limites fondamentales :

  • Absence de contexte session/comportemental : chaque requête est évaluée de manière indépendante. Un scraper qui envoie 10 000 requêtes GET syntaxiquement correctes est totalement invisible pour le CRS.
  • Vulnérabilité aux payloads polymorphiques augmentés par LLM : Osama et al., 2025 (arXiv:2512.23610) démontrent que les WAF basés sur des règles (ModSecurity + CRS) n'ont qu'un taux de blocage de 10 à 14 % contre des payloads d'injection SQL et XSS générés et mutés par LLM, contre 96 à 100 % pour XGBoost entraîné sur des features comportementales. Les LLMs (GPT-4, Claude) peuvent paraphraser les payloads malveillants de manière à préserver leur sémantique d'injection tout en contournant les expressions régulières du CRS.
  • Détection comportementale nulle : un scraper syntaxiquement conforme, sans charge utile malveillante, est structurellement invisible pour le CRS.
  • Coût de maintenance élevé : les nouvelles techniques d'attaque nécessitent des mises à jour manuelles de règles, créant un délai systématique entre l'émergence d'une menace et sa couverture.

2.1.2 Listes de réputation IP et ASN

La deuxième couche de défense statique repose sur des dictionnaires de réputation. Trois structures sont utilisées en production :

dict_bot_ip (IP_TRIE) : dictionnaire de plages CIDR associées à des bots connus, implémenté comme un arbre radix (trie sur les bits de l'adresse IP) permettant une recherche par plus long préfixe en O(k) où k est la longueur de la clé (32 bits pour IPv4, 128 bits pour IPv6). L'opération de lookup par CIDR en O(1) amorti est possible grâce à l'indexation des nœuds internes du trie.

CIDR (Classless Inter-Domain Routing) : notation pour spécifier des plages d'adresses IP, ex. 192.168.1.0/24 désigne les 256 adresses de 192.168.1.0 à 192.168.1.255. Le suffixe /24 indique que les 24 premiers bits sont le préfixe réseau.

ASN (Autonomous System Number) : numéro unique identifiant un système autonome — un groupe de préfixes IP contrôlés par un seul opérateur réseau et partageant une politique de routage unifiée. Exemple : AS15169 = Google, AS32934 = Meta, AS14618 = Amazon AWS. Attribués par les RIR (Regional Internet Registry : ARIN, RIPE NCC, APNIC). Les ASNs sont la base de BGP (Border Gateway Protocol), le protocole de routage inter-domaines d'internet.

dict_bot_ja4 : mapping JA4 hash → bot_name pour les empreintes TLS connues associées à des outils spécifiques.

dict_asn_reputation : mapping ASN → label parmi : human (FAI résidentiel), datacenter (AWS, GCP, Azure, OVH), proxy (Bright Data, Oxylabs), tor (nœuds de sortie Tor), vpn (ExpressVPN, NordVPN), scanner (Shodan, Censys, Masscan), bot (botnets connus).

Limite critique : les botnets résidentiels opèrent depuis des ASNs étiquetés human. Les proxies résidentiels (Bright Data, Oxylabs) vendent un accès à des millions d'adresses IP de particuliers — souvent via des applications mobiles dont les conditions d'utilisation autorisent la réutilisation de la bande passante — pour contourner précisément les listes de réputation ASN. Une adresse IP Bright Data apparaît dans le même sous-réseau qu'un voisin résidentiel légitime, avec le même ASN de FAI. Ce vecteur de contournement est structurellement invisible pour les approches purement basées sur la réputation IP/ASN.

2.1.3 Projet Anubis (TecharoHQ)

Anubis est un système de règles communautaire en YAML permettant de définir des actions granulaires par bot identifié. Les quatre actions disponibles sont :

  • ALLOW : autorisation explicite (bots légitimes : Googlebot, Bingbot, bots de recherche académique)
  • DENY : blocage avec retour 403 Forbidden — signal de vérité terrain fort pour l'entraînement XGBoost
  • WEIGH : ajout d'un score de pondération sans blocage — signal auxiliaire dans le vecteur de features
  • CHALLENGE : redirection vers un challenge (PoW ou CAPTCHA)

Implémentation dans l'architecture : deux structures de lookup sont maintenues en mémoire :

  • dict_anubis_ip : IP_TRIE CIDR pour les correspondances par plage IP
  • dict_anubis_asn : dictionnaire ASN → action/score

Priorité de correspondance : COALESCE(IP match, ASN match) — une correspondance CIDR précise sur l'IP prend la priorité sur la correspondance ASN plus générale. Cela reflète le principe que l'information la plus spécifique est la plus fiable.

Valeur pour le pipeline ML :

  • Les sessions DENY fournissent des étiquettes de bot à haute confiance pour l'entraînement supervisé de XGBoost, sans nécessiter d'annotation manuelle.
  • Les sessions WEIGH contribuent une feature binaire anubis_is_flagged dans la famille F7, enrichissant le vecteur de features sans déclencher de blocage.

2.2 Fingerprinting réseau

2.2.1 TLS Fingerprinting : de JA3 à JA4+

Fondements : le message ClientHello TLS

Lorsqu'un client initie une connexion TLS (Transport Layer Security), il envoie un message ClientHello qui contient les informations suivantes :

  • TLS versions supportées : ex. TLS 1.2, TLS 1.3
  • Cipher suites : paires algorithme de chiffrement symétrique + AEAD proposées par le client, ex. TLS_AES_256_GCM_SHA384 (TLS 1.3), TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (TLS 1.2). Le serveur choisit la suite la plus forte qu'il supporte.
  • Extensions : ensemble de champs optionnels étendant le protocole de base : SNI, ALPN, session ticket, supported_versions, key_share, signature_algorithms, etc.
  • Elliptic curve groups (supported_groups) : courbes elliptiques pour l'échange de clés ECDH, ex. x25519, secp256r1, secp384r1
  • Point formats : formats de compression des points de courbe elliptique (généralement uncompressed uniquement en TLS 1.3)

Ces champs sont déterminés par la pile TLS du client (OpenSSL, BoringSSL, NSS, SChannel) et varient peu d'une connexion à l'autre pour le même client, constituant une empreinte stable et distinctive.

JA3

JA3 (Althouse et al., 2017, Salesforce) est un algorithme de fingerprinting TLS qui calcule le hash MD5 d'une chaîne de valeurs concaténées extraites du ClientHello :

JA3 = MD5(TLSVersion,Ciphers,Extensions,EllipticCurves,EllipticCurvePointFormats)

Exemple : 769,47-53-5-10-49172-49162-49157-49167-49161-100-56-19-49156-49162-49159-49160-22-3,0-10-11,23-24-25,0

JA3 a été largement adopté (Cloudflare, AWS, Akamai, Suricata, Zeek) mais présente deux problèmes fondamentaux :

Instabilité GREASE : RFC 8701 (Generate Random Extensions And Sustain Extensibility) introduit un mécanisme par lequel les clients TLS injectent des valeurs « factices » dans leurs listes de cipher suites et d'extensions. Ces valeurs GREASE (0x0A0A, 0x1A1A, 0x2A2A, 0x3A3A, 0x4A4A, 0x5A5A, 0x6A6A, 0x7A7A, 0x8A8A, 0x9A9A, 0xAAAA, 0xBABA, 0xCACA, 0xDADA, 0xEAEA, 0xFAFA) sont choisies aléatoirement à chaque connexion. L'objectif est de s'assurer que les serveurs ne rejettent pas les extensions inconnues, évitant l'ossification du protocole. Conséquence : deux connexions successives du même navigateur Chrome peuvent produire des JA3 différents en raison du changement des valeurs GREASE, rendant l'empreinte non déterministe.

Collision inter-versions : les mises à jour majeures de navigateur changent la liste des cipher suites supportés, modifiant le JA3 de manière légitime. Un JA3 associé à Chrome 110 est différent de celui de Chrome 120.

JA4

JA4 (Althouse, FoxIO, septembre 2023) est une refonte complète du fingerprinting TLS avec un format lisible par l'humain structuré en trois sections a_b_c :

Section a (lisible par l'humain) : chaîne de 10 caractères encodant les métadonnées structurelles :

  • Type de protocole : t (TCP), q (QUIC), d (DTLS)
  • Version TLS négociée : 13 (TLS 1.3), 12 (TLS 1.2), 10 (TLS 1.0)
  • Nombre de cipher suites (2 chiffres, GREASE filtrés)
  • Nombre d'extensions (2 chiffres, GREASE filtrés)
  • Valeur ALPN de premier choix (h2, h1, 00 si absent)
  • Présence du SNI : d (domain, SNI présent), i (IP, SNI absent)

ALPN (Application-Layer Protocol Negotiation) : extension TLS définie dans RFC 7301 permettant au client d'annoncer les protocoles applicatifs qu'il supporte dans le ClientHello (ex. h2 pour HTTP/2, http/1.1, h3). Le serveur sélectionne un protocole dans la liste et le communique dans le ServerHello. ALPN permet le multiplexage de protocoles sur un même port TLS sans identification de port séparée. Son absence dans un ClientHello signale un client non-navigateur ou une bibliothèque TLS minimaliste.

SNI (Server Name Indication) : extension TLS définie dans RFC 6066 qui envoie le nom d'hôte cible dans le ClientHello, permettant à un serveur d'héberger plusieurs certificats TLS sur une seule adresse IP (hébergement virtuel TLS). Sans SNI, un serveur multi-domaines ne peut pas savoir quel certificat présenter avant que la session TLS soit établie.

Section b : SHA-256 tronqué aux 12 premiers caractères hexadécimaux de la liste de cipher suites triée (GREASE filtrés). Le tri élimine les variations non sémantiques dues à l'ordre aléatoire des cipher suites.

Section c : SHA-256 tronqué aux 12 premiers caractères hexadécimaux de la liste d'extensions triée (GREASE filtrés, codes extensions seulement sans valeurs).

Exemple de JA4 : t13d1516h2_8daaf6152771_e5627efa2ab1

La combinaison du tri et du filtrage GREASE élimine la variabilité non sémantique, produisant une empreinte stable pour le même navigateur entre deux connexions.

Famille JA4+ (12 méthodes)

Nom court Nom complet Signal capturé Couche
JA4 JA4 TLS Client Empreinte ClientHello TLS (version, ciphers, extensions, ALPN, SNI) L5 TLS
JA4S JA4 Server Réponse TLS serveur (version négociée, cipher choisi, extensions) L5 TLS
JA4H JA4 HTTP Ordre et présence des en-têtes HTTP, Accept-Language, cookies L7 HTTP
JA4L JA4 Latency Latence client→serveur (mesure de la distance physique) L4 TCP
JA4LS JA4 Latency Server Latence serveur→client L4 TCP
JA4X JA4 X509 Certificat TLS : algorithme de signature, extensions, OID L5 TLS/X.509
JA4SSH JA4 SSH Échange SSH : kex algorithms, host key, encryption, MAC L5 SSH
JA4T JA4 TCP Paramètres SYN : Window Size, Options TCP, Window Scale, MSS L4 TCP
JA4TS JA4 TCP Server Réponse SYN-ACK serveur L4 TCP
JA4TScan JA4 TCP Scan Fingerprint de scanner TCP actif L4 TCP
JA4+ (composite) Multi-protocol Combinaison JA4+JA4H+JA4T pour cohérence cross-layer L4L7
(en développement)

Adoption en production (2026) : Cloudflare, AWS CloudFront, AWS WAF, Google Cloud Armor, Azure Front Door, Akamai, F5 BIG-IP, Suricata, Zeek, Arkime, VirusTotal, Fastly, Vercel.

2.2.2 TCP Fingerprinting

JA4T capture les paramètres du paquet SYN TCP pour identifier le système d'exploitation et la configuration réseau du client.

Paquet SYN TCP : premier paquet de la poignée de main à trois voies TCP (SYN → SYN-ACK → ACK). Il contient dans son en-tête :

  • MSS (Maximum Segment Size) : taille maximale du payload TCP en octets qu'un segment peut transporter. Pour Ethernet standard (MTU 1500), MSS = 1500 - 20 (IP header) - 20 (TCP header) = 1460 octets. Un MSS réduit (ex. 1380) signale la présence d'un tunnel VPN qui consomme une partie de l'espace disponible pour son propre en-tête d'encapsulation.
  • Window Size : taille du tampon de réception en octets, indiquant combien de données le récepteur peut accepter sans acquittement. Déterminé par l'implémentation de la pile TCP dans le noyau OS.
  • TCP Options : champ extensible contenant des options négociées. Les plus importantes : type 1 (NOP padding), type 2 (MSS), type 3 (Window Scale), type 4 (SACK Permitted), type 8 (Timestamps).
  • Window Scale (RFC 7323) : option TCP définie dans RFC 7323 permettant de dépasser la limite de 65 535 octets du champ Window Size (16 bits). Le facteur d'échelle est un exposant binaire (014) : taille_effective = window_size × 2^scale. Permet des fenêtres TCP jusqu'à 1 Go, indispensable pour les connexions à haute bande passante et forte latence (liaisons satellite, intercontinentales).
  • TTL IP (Time to Live) : compteur décrémenté par chaque routeur traversé. Valeurs initiales typiques : Linux=64, Windows=128, iOS/macOS=64. Après K sauts, TTL_observé = TTL_initial - K, permettant d'inférer TTL_initial et donc l'OS source.

Signatures OS caractéristiques :

OS Window Size Options TCP Window Scale MSS TTL initial
Linux 5.x+ 64240 2-4-8-1-3 7 1460 64
Windows 11 64240 2-4-8-1-3 8 1460 128
macOS 14+ 65535 2-4-8-1-3 6 1460 64
iOS 17+ 65535 2-4-8-1-3 6 (ou absent) 1460 64
Windows (sans TS) 8192 2-4-1-3 2 1460 128

Détection VPN/Tunnel :

  • MSS = 1380 : présence d'un tunnel VPN (overhead d'encapsulation ≈ 80 octets)
  • MSS = 1360 : double encapsulation (VPN sur VPN, ou VPN sur réseau mobile)
  • MSS = 1452 : réseau PPPoE (DSL, certains opérateurs mobiles)

Signatures de scanners :

Outil Window Size Options TCP MSS Comportement caractéristique
Masscan 1024 2 (MSS seulement) 1460 Pas de SACK, pas de timestamps, pas de window scale
ZMap 65535 2-4-8-1-3 1460 Fenêtre maximale
Nmap 1024 2-4-8-1-3 1460 Options standard mais fenêtre minimale
Nmap (SYN stealth) 1024 2-4-1-3 variable Pas de timestamps

Détection de carriers mobiles :

  • AT&T : MSS = 1340 (réseau LTE avec overhead GTP)
  • Verizon : MSS = 1392 (optimisation réseau propriétaire)
  • T-Mobile : MSS = 1420

Features TCP capturées : tcp_meta_window_size, tcp_meta_mss, tcp_meta_window_scale, tcp_meta_options, ip_meta_ttl

Features dérivées : mss_mobile_mismatch (MSS mobile mais UA desktop), no_window_scale_ratio (ratio de connexions sans Window Scale — obsolète ou stack TCP minimal), avg_ttl, ttl_std, ip_df_variance

2.2.3 Fingerprinting TLS avancé

Au-delà du JA4 de base, plusieurs signaux TLS dérivés améliorent la précision de classification :

Ratio de diversité JA3 : count(distinct JA3) / count(distinct JA4). Pour un navigateur légitime, le ratio est proche de 1 (même JA4 stable, légère variation JA3 due à GREASE). Un bot qui randomise les valeurs GREASE pour contourner la détection JA3 produit un ratio élevé (520 JA3 différents pour le même JA4), révélant la stratégie d'évasion elle-même.

Absence d'ALPN (is_alpn_missing) : l'absence de l'extension ALPN dans le ClientHello signale un client non-navigateur. Tous les navigateurs modernes (Chrome, Firefox, Safari) incluent systématiquement ALPN avec h2 et http/1.1 depuis 2016. Les bibliothèques TLS minimalistes (Go crypto/tls configurée minimalement, certaines versions d'OpenSSL sans configuration ALPN) omettent cette extension. Valeur de précision élevée.

Divergence SNI↔Host (sni_host_mismatch) : détecte une discordance entre le nom d'hôte dans le SNI TLS et la valeur de l'en-tête HTTP Host. Cette discordance peut indiquer :

  • Domain fronting : technique d'évasion de censure où le SNI pointe vers un CDN de confiance (ex. cloudfront.net) mais l'en-tête HTTP Host pointe vers le domaine cible réel, masquant la destination dans la couche TLS. Bloqué par la plupart des CDN majeurs depuis 2018 mais encore utilisé dans certains contextes.
  • Proxy mal configuré : un proxy réécrit l'en-tête Host sans mettre à jour la session TLS.
  • Outil d'automatisation : certains frameworks HTTP ne synchronisent pas SNI et Host correctement.

Timing SYN→ClientHello : le délai entre le paquet SYN TCP et le message ClientHello TLS mesure le temps nécessaire au client pour initier la négociation TLS après l'établissement de la connexion TCP. Variance et coefficient de variation (tcp_jitter_variance, syn_timing_cv) : les scripts automatisés montrent une variance proche de zéro (délai constant, déterminé par le code), les humains montrent une variance naturelle (réseau + délai de clavier/application).


2.3 Analyse comportementale HTTP

2.3.1 Signaux d'en-têtes HTTP

Les navigateurs web modernes envoient un ensemble précis d'en-têtes HTTP à chaque requête. L'absence ou la déformation de ces en-têtes constitue un signal de détection fiable pour les clients non-navigateurs.

En-tête Signification Comportement navigateur Signal bot si absent/anormal
Accept-Language Préférence de langue, ex. fr-FR,fr;q=0.9,en;q=0.8 Toujours présent Souvent absent dans les scripts
Accept-Encoding Encodages supportés : gzip, deflate, br Inclut br (Brotli, RFC 7932) depuis Chrome 49 (2016) Absence de br = client pré-2016 ou non-navigateur
Sec-Fetch-Site Origine de la requête : same-origin, cross-site, none Présent depuis Chrome 76, Firefox 90 Jamais généré par les non-navigateurs
Sec-Fetch-Mode Mode de la requête : navigate, cors, no-cors, same-origin Présent, valeur sémantique stricte Signal d'authenticité très fort si cohérent
Sec-Fetch-Dest Destination : document, script, image, style, etc. Présent, cohérent avec le type de ressource Incohérence = navigation simulée
Sec-Fetch-User Initié par l'utilisateur : ?1 Présent sur les navigations top-level utilisateur Absent sur requêtes programmatiques
Sec-CH-UA Client Hints UA : "Chromium";v="120", "Not(A:Brand";v="24" Envoyé par Chromium depuis Chrome 89 Absent dans les non-Chromium
Sec-CH-UA-Mobile Indicateur mobile : ?0 (desktop) ou ?1 (mobile) Cohérent avec l'UA et le type d'appareil ?1 avec UA desktop = mismatch
Sec-CH-UA-Platform Plateforme : "Windows", "macOS", "Linux", "Android" Cohérent avec l'OS dans l'UA Incohérence détectable
Cookie Cookies de session et tracking Maintenu automatiquement par le navigateur Absent pour les bots stateless
Referer URL d'où provient la requête Présent lors de la navigation dans une page Absent = accès direct (typique des bots)
Ordre des en-têtes Séquence fixe propre à chaque implémentation Chrome: Host, Connection, sec-ch-ua... Ordre non-Chrome révèle la bibliothèque réelle

Fetch Metadata : les en-têtes Sec-Fetch-* sont définis dans la spécification W3C Fetch Metadata et envoyés automatiquement par les navigateurs Chromium (depuis Chrome 76, 2019) et Firefox (depuis Firefox 90, 2021). Ils fournissent au serveur des informations sur le contexte de la requête : est-elle initiée par l'utilisateur ? Par un script cross-origin ? Vers une iframe ? Ces en-têtes ne sont jamais générés par des bibliothèques HTTP non-navigateur (Python requests, curl, Go net/http, Node.js fetch de base).

Brotli : algorithme de compression RFC 7932 développé par Google, plus efficace que gzip (1525 % de compression supplémentaire). Supporté nativement par tous les navigateurs modernes depuis 2016. L'absence de br dans Accept-Encoding indique fortement un client non-navigateur ou une très vieille version.

Client Hints : mécanisme MDN Client Hints permettant aux navigateurs Chromium d'envoyer des informations structurées sur le client (UA, plateforme, mobilité) à travers des en-têtes Sec-CH-* standardisés. Le ua_ch_mismatch détecte une incohérence entre Sec-CH-UA-Mobile: ?1 (mobile) et un User-Agent desktop, ou l'absence de Sec-CH-UA dans un UA se revendiquant Chrome récent.

Features extraites : has_accept_language, has_cookie, has_referer, sec_fetch_absence_rate (ratio de requêtes sans Sec-Fetch), generic_accept_ratio (ratio Accept générique */*), missing_accept_enc_ratio, modern_browser_score, ua_ch_mismatch, header_count, header_order_confidence

2.3.2 Patterns de navigation

Les patterns de navigation à travers un site web distinguent les comportements humains des comportements automatisés selon plusieurs dimensions :

asset_ratio : count_assets / hits où count_assets = requêtes vers CSS, JavaScript, images, fonts. Un navigateur humain charge typiquement 60 à 80 % de ressources statiques pour chaque page HTML visitée (chargement du template, des scripts, des images). Un scraper qui n'extrait que le HTML produit un asset_ratio proche de 0. Valeurs typiques : navigateur humain 0.60.8, scraper HTML 0.010.05, bot API 0.

direct_access_ratio : ratio de requêtes sans en-tête Referer. Les humains naviguent en suivant des liens (Referer présent sauf première page), les bots accèdent directement aux URLs. Valeurs : humain 0.10.3, bot de scraping 0.71.0.

path_diversity_ratio : uniq_paths / hits. Un crawler systématique accède à une URL différente à chaque requête (ratio ≈ 1). Un bot répétitif accède toujours au même chemin (ratio ≈ 0.01). La navigation humaine est intermédiaire (0.30.8) car les utilisateurs visitent plusieurs pages mais revisitent parfois certaines.

url_depth_variance : variance de la profondeur des URLs (nombre de / dans le chemin). Un crawler systématique parcourt méthodiquement une profondeur fixe (variance faible). La navigation humaine génère une variance naturelle.

2.3.3 Brute-force et credential stuffing

Les attaques d'authentification par force brute et credential stuffing (utilisation de couples identifiant/mot de passe volés) produisent des patterns comportementaux distincts :

fuzzing_index : uniq_query_params / uniq_paths. Un fuzzer d'API teste de nombreuses valeurs de paramètres sur un nombre restreint d'endpoints (ratio élevé, ex. 50 paramètres différents sur /api/search → ratio 50). La navigation normale génère environ autant de chemins distincts que de paramètres distincts (ratio ≈ 1).

post_ratio : count_POST / hits. Un trafic normal a un faible ratio de requêtes POST (soumissions de formulaires). Un attaquant en credential stuffing maintient un ratio POST élevé (0.51.0) car chaque tentative d'authentification est un POST.

count_login_post : compteur direct des requêtes POST vers les endpoints d'authentification (/login, /signin, /auth, /wp-login.php, /account/login). Valeurs : humain 02 par session, credential stuffer 10010 000.

login_post_concentration : count_login_post / total_POST — mesure si les POSTs se concentrent sur les endpoints de connexion, distinguant un utilisateur qui utilise beaucoup de formulaires d'un attaquant ciblant uniquement l'authentification.


2.4 Apprentissage automatique pour la détection d'intrusions

2.4.1 Approches supervisées et leurs limites

XGBoost (eXtreme Gradient Boosting)

XGBoost (Chen & Guestrin, 2016) est un algorithme d'ensemble d'arbres de décision entraînés séquentiellement (boosting). Principe : chaque arbre est entraîné pour corriger les erreurs résiduelles de l'ensemble des arbres précédents, en minimisant un gradient de la fonction de perte. La "descente de gradient" s'effectue dans l'espace des fonctions (arbres) plutôt que dans l'espace des paramètres.

Mécanisme technique :

  1. Initialisation : prédiction initiale constante f0(x) = argmin Σ L(yi, γ)
  2. Pour chaque itération m = 1,...,M :
    • Calcul des résidus pseudo-gradients : rim = -[∂L(yi, F(xi)) / ∂F(xi)] pour chaque xi
    • Entraînement d'un arbre hm sur les résidus rim
    • Mise à jour : F_m(x) = F_{m-1}(x) + η × hm(x) où η est le learning rate
  3. La prédiction finale est : F(x) = f0(x) + Σ η × hm(x)

Optimisations XGBoost :

  • Parallélisation : la construction de chaque arbre est parallélisée par sous-échantillonnage de colonnes (colsample_bytree) et par tri par histogramme (histogram approximation du split optimal)
  • Régularisation L1/L2 : termes de régularisation ajoutés à la fonction objectif pour contrôler la complexité des arbres
  • Hyperparamètres clés : max_depth (profondeur maximale des arbres), n_estimators (nombre d'arbres), learning_rate (η), subsample (fraction des lignes par arbre), colsample_bytree (fraction des features par arbre)

Performances : Osama et al., 2025 (arXiv:2512.23610) rapportent 99,59 % de précision et une inférence en microsecondes pour XGBoost sur des features comportementales de bot detection, contre 1014 % de blocage pour les WAF à règles face aux mêmes payloads augmentés par LLM.

Limites des approches supervisées :

  • Concept drift : un modèle entraîné sur des bots de 2024 peut être aveugle aux nouvelles techniques de 2025
  • Rareté des étiquettes : annoter manuellement des millions de sessions HTTP est coûteux et sujet à erreur
  • Bruit des étiquettes : les labels fournis par les analystes SOC contiennent des erreurs systématiques (faux positifs mal corrigés, biais de confirmation). Ces étiquettes bruitées empoisonnent le modèle supervisé — un problème bien documenté par Northcutt et al., 2021 (Cleanlab) qui montre que les jeux de données réels contiennent 8 à 20 % de labels incorrects. Pour mitiger ce risque, notre pipeline intègre un filtre Cleanlab avant l'entraînement XGBoost (détail §3.8).
  • Biais de jeu de données : les modèles entraînés sur des données de laboratoire (CICIDS2017, NSL-KDD) généralisent mal au trafic en production, comme documenté dans la littérature sur les benchmarks de détection d'intrusions
  • Attaque par évasion adversariale : un attaquant ayant accès ou connaissance du modèle peut crafting des sessions qui maximisent le score de légitimité

2.4.2 Approches semi-supervisées

Isolation Forest (Liu et al., 2008)

Isolation Forest (Liu, Ting, Zhou, ICDM 2008) est un algorithme de détection d'anomalies basé sur la notion d'isolation aléatoire. Insight fondamental : les anomalies, étant rares et différentes des points normaux, sont isolées plus rapidement (en moins de partitions récursives) que les points normaux.

Algorithme :

  1. Pour chaque arbre d'isolation (n_estimators arbres) :
    • Sélectionner aléatoirement ψ points (sous-échantillon)
    • Construire récursivement une partition binaire : (a) choisir une feature aléatoire q, (b) choisir un seuil p uniformément entre min(q) et max(q), (c) partitionner en q ≤ p et q > p, jusqu'à isolation de chaque point
  2. Le score d'anomalie d'un point x est inversement proportionnel à la longueur moyenne du chemin d'isolation :
score(x, n) = 2^( -E[h(x)] / c(n) )

où E[h(x)] est la longueur de chemin moyenne à travers tous les arbres, et c(n) = 2H(n-1) - 2(n-1)/n est la longueur de chemin moyenne attendue dans une BST (Binary Search Tree) unsuccessful, avec H(i) = ln(i) + 0.5772 (constante d'Euler-Mascheroni).

Un score proche de 1 indique une anomalie (chemin court, isolé rapidement) ; un score proche de 0.5 est normal ; un score < 0.5 est clairement normal.

Extended Isolation Forest (EIF)

Extended Isolation Forest (Hariri, Kind, Brunner, IEEE TKDE 2021) résout un problème fondamental de l'Isolation Forest standard dans les espaces à haute dimension.

Problème des « fantômes de clusters » (ghost clusters) : l'IF standard utilise des coupes axis-alignées (hyperplans parallèles aux axes des features). En haute dimension (> 10 features), cette stratégie produit des artéfacts géométriques : des zones de l'espace des features sans données reçoivent artificellement des scores d'anomalie bas, car les coupes parallèles aux axes ont tendance à partitionner les régions denses (là où se concentrent les données normales) plutôt que les régions vides aux frontières. Ces zones vides — les « fantômes de clusters » — sont des minima artificiels du score d'anomalie créés par la géométrie des hyperplans axis-alignés, et non par la présence réelle de données normales.

Solution EIF : remplacer les coupes axis-alignées par des hyperplans à pente aléatoire. À chaque nœud de l'arbre :

  1. Choisir un vecteur normal aléatoire n ∈ ^d (uniform sur la sphère unité)
  2. Choisir un point d'interception aléatoire p ∈ [min(X·n), max(X·n)]
  3. Partitionner : {x : x·n ≤ p} et {x : x·n > p}

Résultat : les coupes ne sont plus liées aux axes, éliminant les artéfacts géométriques. Les scores d'anomalie deviennent cohérents et fiables, particulièrement dans les espaces à 4759 dimensions de notre architecture.

Relation IF/EIF : l'IF standard est un cas particulier de EIF avec extension_level=0 (vecteur normal aligné sur un seul axe aléatoire).

Implémentation : bibliothèque isotree (Cortes, 2021+) — implémentation C++ native avec interface Python. Paramètres de production : ntrees=300, contamination=0.001.

Calibration des scores : isotree retourne un score ∈ [0, 1] où > 0.5 = anomalie. Transformation pour compatibilité sklearn : sklearn_equiv = 0.5 - isotree_score (négatif = anomalie). Le modèle est sérialisé avec joblib accompagné des statistiques de baseline (quantiles par feature : p10, p25, p50, p75, p90) pour la détection de dérive.

Architecture bifurquée EIF :

Deux modèles EIF s'exécutent en parallèle à chaque cycle de 300 secondes :

  • Modèle Complet (≈ 45 features, L3→L7) : appliqué sur les sessions pour lesquelles ja4ebpf a pu corréler les métadonnées TCP/TLS avec la requête HTTP (données L3/L4 disponibles). Inclut toutes les features des familles F1F7.
  • Modèle Applicatif (≈ 35 features, L7 uniquement) : appliqué sur les sessions dont les données TCP/TLS sont absentes — trafic passant par un CDN ou proxy qui ne permet pas la corrélation TCP/TLS. Utiliser les features TCP/TLS imputées à zéro pour ce modèle introduirait un biais systématique.

La bifurcation est justifiée par le fait que les features TCP/TLS ne sont disponibles que lorsque ja4ebpf a corrélé la connexion réseau avec la requête HTTP. Imputer ces features à zéro pour le trafic non corrélé créerait un signal artificiel (zéro n'est pas neutre pour un EIF — il est interprété comme une valeur réelle).

2.4.2b Autoencoders (AE) et détection d'anomalies

Principe des autoencoders

Un autoencodeur est un réseau de neurones entraîné à reconstruire son entrée après compression à travers un espace latent de dimension réduite (bottleneck). Architecture :

Encodeur : x (dim D) → z (dim d, d << D)
Décodeur : z (dim d) → x̂ (dim D)

Entraîné à minimiser l'erreur de reconstruction :

MSE = (1/n) × Σ(xi - x̂i)²

Le bottleneck (espace latent dimension 16 << dimension d'entrée 4559) force le réseau à apprendre la représentation la plus compacte du trafic normal. L'erreur de reconstruction est le score d'anomalie : les échantillons normaux se reconstruisent bien (MSE faible) ; les anomalies se reconstruisent mal (MSE élevé) car le réseau n'a jamais été entraîné sur des patterns de bot.

Avantage fondamental sur EIF : l'AE capture les corrélations non-linéaires entre features. Un bot utilisant httpcloak peut imiter individuellement chaque feature Chrome (JA4 correct, ALPN correct, en-têtes HTTP corrects) mais leurs inter-corrélations inhabituelles (tcp_jitter_variance × sec_fetch_absence_rate × asset_ratio) trahissent l'imitation dans l'espace de reconstruction de l'AE. EIF détecte les anomalies ponctuelles (points isolés dans l'espace des features) ; l'AE détecte les anomalies distributionnelles (corrélations inter-features anormales).

Implémentation : PyTorch, espace latent 16 dimensions, arrêt précoce sur la loss de validation, score d'anomalie = erreur de reconstruction MSE.

Kitsune

Kitsune (Mirsky et al., NDSS 2018) est un NIDS (Network Intrusion Detection System) en ligne basé sur un ensemble d'autoencoders légers (KitNET). Architecture : N petits autoencoders (~64 neurones chacun) correspondant à des groupes de features corrélées, dont les erreurs de reconstruction sont agrégées par un autoencodeur de sortie servant de vote non-linéaire. Démonstration que de petits AE sur Raspberry Pi atteignent des performances comparables aux détecteurs hors ligne, validant l'approche d'ensemble d'AE pour la détection d'intrusions en production.

β-VAE

Les Variational Autoencoders (VAE) ajoutent une régularisation KL-divergence structurant l'espace latent. La KL-divergence (divergence de Kullback-Leibler) mesure comment une distribution de probabilité P diffère d'une distribution de référence Q :

KL(P||Q) = Σ P(x) × log(P(x)/Q(x))

Pour un VAE, la régularisation KL(q(z|x) || p(z)) pénalise l'encodeur si sa distribution postérieure q(z|x) s'éloigne d'une normale standard p(z) = N(0, I). Score d'anomalie VAE : -log p(x|z) + KL(q(z|x) || p(z)). Cette régularisation rend l'espace latent plus lisse et mieux organisé, potentiellement améliorant la qualité du clustering HDBSCAN.

Complémentarité AE + IF

La complémentarité entre IF et AE est un résultat bien établi en détection d'anomalies :

Critère Isolation Forest (EIF) Autoencoder (AE)
Type d'anomalie détecté Points isolés dans l'espace des features Corrélations non-linéaires anormales
Interprétabilité ExIFFI (profondeur d'isolation par feature) Erreur par dimension
Dimensionnalité Optimal jusqu'à ~100 features Robuste, compresse l'espace
Détection d'imitation Partielle Plus forte (corrélations inter-features)
Espace pour clustering Non adapté Espace latent 16D idéal pour HDBSCAN
Coût computationnel Faible (arbres) Modéré (réseau de neurones)

Espace latent AE pour HDBSCAN : les 16 dimensions latentes de l'AE capturent la variance la plus discriminante du comportement des bots. Le clustering HDBSCAN dans cet espace regroupe les sessions dont le comportement compressé est similaire — c'est-à-dire les bots utilisant le même outil ou la même configuration — identifiant ainsi les campagnes coordonnées.

2.4.2c Ensembles hybrides supervisé + non-supervisé

Architecture triple-voix

Le système de détection combine trois « voix » complémentaires :

                    ┌─────────────────────┐
                    │   Vecteur de 85     │
                    │   features par      │
                    │   session (5min)    │
                    └────────┬────────────┘
                             │
              ┌──────────────┼──────────────┐
              │              │              │
        ┌─────▼─────┐  ┌─────▼─────┐  ┌────▼──────┐
        │   EIF     │  │   AE      │  │ XGBoost   │
        │ (semi-    │  │ (semi-    │  │(supervisé)│
        │supervisé) │  │supervisé) │  │           │
        └─────┬─────┘  └─────┬─────┘  └────┬──────┘
              │              │              │
        eif_norm       ae_norm          xgb_prob
              │              │              │
              └──────────────┼──────────────┘
                             │
                    ┌────────▼────────┐
                    │  Fusion LR    │
                    │ (régression     │
                    │  logistique,    │
                    │  ≥1000 labels)  │
                    └────────┬────────┘
                             │
                    ┌────────▼────────┐
                    │  score_final    │
                    │  → étiquette    │
                    └─────────────────┘

Formule de combinaison :

final = (1 - XGB_WEIGHT) × ((1 - AE_WEIGHT) × eif_norm + AE_WEIGHT × ae_norm) \
      + XGB_WEIGHT × xgb_prob

Valeurs par défaut : AE_WEIGHT=0.30, XGB_WEIGHT=0.20. Configurable via variables d'environnement pour ajustement en production sans modification du code.

Fusion LR

Le Fusion LR est une régression logistique activée lorsqu'au moins 1 000 étiquettes ont été accumulées (sessions DENY Anubis + annotations manuelles + seuillage de confiance).

Régression logistique : modèle linéaire probabiliste qui apprend des poids w pour chaque signal intermédiaire en minimisant l'entropie croisée binaire sur les étiquettes accumulées :

P(bot) = σ(w1×eif + w2×ae + w3×xgb + w4×volume + bias)

σ est la fonction sigmoïde : σ(z) = 1 / (1 + e^{-z})

Les poids w1w4 sont appris, permettant au système de calibrer automatiquement l'importance relative de chaque voix en fonction du type de trafic en production. En dessous de 1 000 étiquettes, le système revient aux poids fixes : (eif: 0.50, ae: 0.30, xgb: 0.20).

Calendrier de retraining :

  • XGBoost : hebdomadaire sur les étiquettes accumulées, après filtrage Cleanlab des labels SOC bruyants (voir ci-dessous)
  • EIF : toutes les 24 heures
  • AE : continu avec arrêt précoce sur la loss de validation

Filtrage des labels SOC bruyants (Cleanlab) :

Avant chaque entraînement XGBoost, les labels fournis par les analystes SOC sont filtrés via Cleanlab (Northcutt et al., 2021). Ce framework de confident learning identifie les exemples dont l'étiquette est probablement erronée en comparant les prédictions out-of-fold d'un modèle aux labels observés.

# 1. Obtenir pred_probs via cross-validation (3 folds)
quick_model = XGBClassifier(n_estimators=80, max_depth=4)
pred_probs = cross_val_predict(quick_model, X, y, cv=3, method='predict_proba')

# 2. Identifier les labels douteux
issues = find_label_issues(labels=y, pred_probs=pred_probs)

# 3. Exclure les exemples bruités avant l'entraînement final
X_clean, y_clean = X[~noisy_mask], y[~noisy_mask]

Ce mécanisme protège le modèle contre l'empoisonnement par des faux positifs mal corrigés ou des biais de confirmation des analystes. Le taux de labels filtrés est loggé pour surveillance. En cas d'échec de Cleanlab (erreur mémoire, dépendance manquante), le pipeline revient aux données brutes sans interruption.

2.4.3 Concept Drift et retraining adaptatif

Définition du concept drift

En apprentissage automatique, le concept drift désigne le changement des propriétés statistiques de la variable cible ou de la distribution d'entrée dans le temps, causant une dégradation des prédictions du modèle. Types :

  • Drift soudain : changement abrupt (ex. mise à jour majeure du navigateur modifiant les valeurs JA4)
  • Drift graduel : évolution progressive (ex. changement des patterns de navigation au fil des mois)
  • Drift récurrent : patterns saisonniers (ex. comportements différents le weekend vs. la semaine)
  • Drift incrémental : dérive lente et continue (ex. adaptation progressive des techniques d'évasion)

En détection de bots, le drift adversarial est particulièrement critique : les attaquants adaptent délibérément leurs outils pour contourner les modèles déployés.

Test de Kolmogorov-Smirnov

Le test KS (Kolmogorov-Smirnov) mesure la différence maximale entre deux fonctions de distribution empiriques cumulées (ECDF) :

D = max|F1(x) - F2(x)|

où F1 et F2 sont les ECDFs de la distribution courante et de la distribution de référence (baseline). Si D dépasse la valeur critique (déterminée par les tables de la distribution KS pour un niveau de confiance α), les deux échantillons sont considérés comme provenant de distributions différentes. Avantage : test non-paramétrique, aucune hypothèse sur la forme de la distribution.

Méthode de détection de dérive :

  1. Sauvegarde avec chaque modèle sérialisé de l'approximation 5-quantiles par feature : (p10, p25, p50, p75, p90)
  2. Génération d'échantillons synthétiques par interpolation de la CDF inverse (quantile function)
  3. Test KS + divergence KL sur chaque feature entre la distribution courante et la baseline
  4. Feature marquée comme « en dérive » si le test KS OU la divergence KL dépasse le seuil configuré
  5. Retraining forcé si > 30 % des features dérivent simultanément
  6. Détection de dérive adversariale : si de nombreuses features dérivent simultanément dans la même direction (score de corrélation directionnelle élevé), génération d'une alerte spécifique distinguant la manipulation intentionnelle (dérive adversariale coordonnée) de l'évolution organique (mises à jour navigateur ou changements de comportement naturels)

Validation gate : si le taux d'anomalie sur le jeu de validation dépasse 20 % après retraining, le nouveau modèle est rejeté et le modèle précédent est conservé, avec génération d'une alerte (baseline contaminée).

Limites de l'approximation 5-quantiles : adéquate pour les distributions unimodales, mais peut manquer les dérives bimodales dans asset_ratio, post_ratio, orphan_ratio. Extension à p5/p95 ou à t-digest identifiée comme travail futur.

2.4.4 Modélisation des phases d'attaque

La modélisation des phases d'attaque (Reconnaissance → Mouvement latéral → Intrusion → Exfiltration) par des modèles d'état-espace ou des processus de Markov cachés constitue une piste de recherche. L'enrichissement du clustering HDBSCAN avec ce signal de phase permettrait de distinguer des campagnes en phase de reconnaissance de campagnes en phase d'exploitation active.

La modélisation des phases d'attaque par des modèles d'état-espace ou des processus de Markov cachés constitue une piste de recherche pour distinguer les campagnes en phase de reconnaissance de celles en phase d'exploitation active.

2.4.5 Explicabilité par SHAP et ExIFFI

SHAP (SHapley Additive exPlanations)

SHAP (Lundberg & Lee, 2017, shap.readthedocs.io) est un framework d'explicabilité locale basé sur la théorie des jeux coopératifs (valeurs de Shapley). La contribution d'une feature i à la prédiction pour un exemple x est définie comme sa contribution marginale moyenne sur toutes les ordonnances possibles des features :

φi(f, x) = Σ_{S ⊆ F\{i}} [|S|!(|F|-|S|-1)!/|F|!] × [f(S{i}) - f(S)]

où F est l'ensemble de toutes les features, S est un sous-ensemble, et f(S) est la prédiction du modèle en utilisant seulement les features dans S (les autres étant marginalisées).

SHAP TreeExplainer est une implémentation exacte et efficace pour les modèles basés sur des arbres (XGBoost, Random Forest, LightGBM) en complexité O(TLD²) où T = nombre d'arbres, L = nombre de feuilles, D = profondeur maximale — beaucoup plus rapide que l'estimation par permutation (O(2^|F|)).

ExIFFI (Extended Isolation Forest Feature Importance)

L'importance des features par profondeur d'isolation (approche de type ExIFFI) est une méthode native d'importance des features pour EIF, basée sur la profondeur moyenne d'isolation par feature. Principe : une feature ayant une profondeur d'isolation moyenne faible (isole rapidement les anomalies) est plus importante pour la détection. Activé comme fallback lorsque SHAP n'est pas disponible. Comparé aux top-5 SHAP dans l'interface SOC.

Erreur de reconstruction AE par dimension : (xi - x̂i)² par dimension d'entrée identifie quelles features contribuent à l'anomalie AE. Cela fournit une explicabilité locale pour chaque session anormale : les features dont la reconstruction est la plus dégradée sont les plus discriminantes.


Approches émergentes : GNN et Transformers

L'analyse de séquences de navigation et la détection de flottes distribuées bénéficient également d'approches plus récentes :

  • Graph Neural Networks (GNN) : les GNN opèrent directement sur des graphes de co-occurrence (par exemple IP↔JA4 ou IP↔chemin), apprenant des embeddings de nœuds qui capturent la structure topologique des flottes. Par rapport à la détection de communautés Louvain utilisée dans cette architecture, les GNN offrent une capacité de généralisation supérieure mais nécessitent un volume de données d'entraînement labellisées significatif.

  • Transformers pour l'analyse de séquences : les architectures Transformer (self-attention) permettent de modéliser les dépendances longues dans les séquences de chemins ou les séries temporelles d'intervalles inter-requêtes, capturant des patterns que les chaînes de Markov d'ordre 1 ne peuvent pas représenter.

Cette architecture utilise des méthodes plus légères (Louvain, Markov d'ordre 1, HDBSCAN) en raison de contraintes opérationnelles : pas de données labellisées en volume suffisant, inférence en temps réel sur des cycles de 300 secondes, et interopérabilité avec les outils du SOC.


2.5 Détection côté client (Browser Fingerprinting)

2.5.1 JavaScript Challenges

Les challenges JavaScript constituent la principale approche de détection côté client : injection de code JS dans les pages pour collecter Canvas fingerprint, WebGL renderer, propriétés du navigateur, timing d'exécution JS, et soumettre ces données au serveur pour scoring.

Principaux acteurs : Cloudflare Turnstile, DataDome, PerimeterX (HUMAN Security), Akamai Bot Manager, Shape Security.

Limites :

  • Contournement par navigateurs sans tête patchés : BotBrowser et CloakBrowser annoncent « 30/30 tests passés » sur les suites de détection standard comme botcheck.me, creepjs, et les challenges Cloudflare. Ces outils patchent Chromium au niveau binaire pour supprimer les artefacts d'automatisation (navigator.webdriver, propriétés __proto__ de l'injection Selenium, etc.) et spoofer les valeurs Canvas/WebGL.
  • Inapplicabilité aux APIs : les endpoints d'API ne peuvent pas injecter de JavaScript. Toute protection API repose nécessairement sur des signaux passifs côté serveur.
  • Pénalité de latence : le challenge ajoute une requête supplémentaire (et parfois un délai intentionnel de preuve de travail) à la première visite, dégradant l'expérience utilisateur.

Position de cette architecture : 100 % passive, aucun challenge JavaScript. L'ensemble des signaux de détection provient de l'analyse des paquets réseau et des en-têtes HTTP.

2.5.2 FingerprintJS BotD

FingerprintJS BotD est une bibliothèque JavaScript côté client qui détecte les frameworks d'automatisation en inspectant :

  • navigator.webdriver : propriété mise à true par Selenium et certaines versions de Puppeteer
  • Artefacts Phantom (window.__phantom, window.callPhantom)
  • Artefacts Selenium (window.selenium, document.__webdriver_evaluate)
  • Propriétés de prototypes modifiées par les injections automatisées

Limitation : contournable par des patches bas niveau comme rebrowser-patches, qui modifient directement le runtime V8 et les propriétés exposées par Chromium.

2.5.3 Fingerprinting HTTP/2 passif côté serveur

HTTP/2 : fondements du protocole

HTTP/2 (RFC 7540, remplacé par RFC 9113 en 2022) est un protocole binaire multiplexé remplaçant HTTP/1.1 pour les connexions TLS. Caractéristiques fondamentales :

Framing binaire : toute communication HTTP/2 est découpée en frames de type : HEADERS, DATA, SETTINGS, WINDOW_UPDATE, PRIORITY, RST_STREAM, PUSH_PROMISE, PING, GOAWAY, CONTINUATION. Chaque frame a un en-tête de 9 octets contenant la longueur, le type, les flags et l'identifiant de stream.

Multiplexage : plusieurs streams HTTP/2 coexistent sur une seule connexion TCP, chacun identifié par un stream ID (impair pour les streams initiés par le client : 1, 3, 5...). Élimine le head-of-line blocking de HTTP/1.1 pipelines.

Compression d'en-têtes HPACK : RFC 7541 définit HPACK, qui compresse les en-têtes HTTP/2 via :

  1. Table statique : 61 paires nom/valeur prédéfinies (ex. entrée 1 = :authority, entrée 5 = :path /). Référencées par index 161.
  2. Table dynamique : paires ajoutées dynamiquement au fur et à mesure de la connexion, référencées par index 62+.
  3. Codage Huffman : pour les valeurs littérales, encodage Huffman réduit la taille de 2030 %. Résultat : réduction de la taille des en-têtes de 8588 % par rapport à HTTP/1.1.

Pseudo-headers : HTTP/2 remplace la ligne de requête HTTP/1.1 (GET /path HTTP/1.1) par quatre pseudo-headers préfixés par : : :method, :path, :scheme, :authority.

Contrôle de flux (Flow Control) : RFC 7540 §5.2 empêche un émetteur rapide de saturer un récepteur lent. Deux niveaux : par stream (stream-level) et par connexion (connection-level). Les frames WINDOW_UPDATE incrémentent la fenêtre de contrôle de flux d'un montant spécifié.

Fingerprinting HTTP/2 passif

L'approche de fingerprinting passif HTTP/2 (Bartlett, Cloudflare, 2023, Akamai Client Fingerprint) extrait des signaux depuis les frames HTTP/2 reçues par le serveur immédiatement après l'établissement de la connexion.

Avantage fondamental : le fingerprint HTTP/2 est produit par la couche transport, en dessous du niveau applicatif. Un outil d'évasion doit implémenter une pile HTTP/2 complète et fidèle à un navigateur cible pour l'éviter — effort d'ingénierie significativement supérieur à la simple rotation d'un User-Agent.

Frame SETTINGS (RFC 7540 §6.5) :

Envoyée immédiatement par le client après le préambule de connexion (PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n). Contient des paires clé-valeur identifiant les paramètres de la session HTTP/2 :

ID Nom Signification
1 HEADER_TABLE_SIZE Taille maximale de la table de compression HPACK (octets)
2 ENABLE_PUSH Activation du Server Push HTTP/2 (0=désactivé, 1=activé)
3 MAX_CONCURRENT_STREAMS Nombre maximum de streams simultanés
4 INITIAL_WINDOW_SIZE Taille initiale de la fenêtre de contrôle de flux par stream (octets)
5 MAX_FRAME_SIZE Taille maximale des frames (octets, min 16384)
6 MAX_HEADER_LIST_SIZE Taille maximale de la liste d'en-têtes (octets)
8 ENABLE_CONNECT_PROTOCOL RFC 8441 - WebSocket over HTTP/2

Valeurs caractéristiques par implémentation :

Client HEADER_TABLE_SIZE ENABLE_PUSH MAX_CONCURRENT_STREAMS INITIAL_WINDOW_SIZE MAX_FRAME_SIZE MAX_HEADER_LIST_SIZE
Chrome 119+ 65536 0 1000 6291456 16384 262144
Firefox 90+ 65536 0 100 131072 16384 absent
Safari 15+ 4096 0 100 2097152 16384 absent
curl 7.x 0 (absent) 0 (absent) — (min settings)
Python httpx 65536 0 100 65535 16384 absent
Go net/http 4096 0 250 1048576 16384 absent
Node.js http2 4096 0 100 65535 16384 absent

WINDOW_UPDATE :

Après l'échange SETTINGS, le client envoie une frame WINDOW_UPDATE incrémentant la fenêtre de contrôle de flux de connexion. Cette valeur est fixe par implémentation et constitue un signal très discriminant :

Client Incrément WINDOW_UPDATE
Chrome 119+ 15 663 105 (± 1 000)
Firefox 90+ 12 517 377 (± 1 000)
Safari 15+ 10 420 225 (± 1 000)
curl absent (0)
Python httpx absent (0)
Go net/http 1 073 676 289 (± 1 000)
Node.js http2 65535 (valeur par défaut)

Ordre des pseudo-headers :

L'ordre dans lequel les pseudo-headers :method, :authority, :scheme, :path apparaissent dans la première frame HEADERS est fixe par implémentation (abréviation : m=method, a=authority, s=scheme, p=path) :

Client Ordre pseudo-headers
Chrome 119+ m a s p
Firefox 90+ m p a s
Safari 15+ m s p a
curl m p s a
Python httpx m p s a (comme curl)
Go net/http m s a p

Frames PRIORITY :

Firefox 90+ envoie des frames PRIORITY de démarrage pour les streams 3, 5, 7, 9, 11, 13 avant d'initier la première vraie requête. Chrome ≥ 119 n'envoie plus de frames PRIORITY (migration vers RFC 9218 Extended PRIORITY_UPDATE). Safari n'envoie pas de frames PRIORITY.

Format fingerprint composite (format Akamai) :

SETTINGS[HEADER_TABLE_SIZE,ENABLE_PUSH,MAX_CONCURRENT_STREAMS,INITIAL_WINDOW_SIZE,MAX_FRAME_SIZE,MAX_HEADER_LIST_SIZE]|WINDOW_UPDATE[increment]|PRIORITY[stream:exclusive:dep:weight...]|PSEUDO_HEADER_ORDER[m,a,s,p]

Exemple Chrome 119 :

1:65536,2:0,3:1000,4:6291456,5:16384,6:262144|WU:15663105|noPRIORITY|masp

Cas d'étude httpcloak :

httpcloak est un outil d'évasion qui tente d'imiter l'empreinte TLS de Chrome. Il réussit à reproduire correctement le JA4 Chrome (SETTINGS H2 et WINDOW_UPDATE), mais son ordre de pseudo-headers par défaut correspond à l'ordre curl (mpsa) plutôt qu'à l'ordre Chrome (masp). Cette incohérence entre la couche L5 (TLS : empreinte Chrome) et la couche L7 (HTTP/2 : ordre curl) crée un signal de détection à haute précision : score de browser_matcher ≈ 0.60, plaçant la session dans la zone grise et déclenchant l'analyse EIF + AE.


2.6 Synthèse des limites de l'état de l'art

Technique Limite principale Mitigation dans cette architecture
Règles statiques CRS Aveugle au trafic syntaxiquement correct Couche comportementale ML (F1F8)
Listes IP/ASN Botnets résidentiels échappent aux blacklists ASN = feature parmi d'autres, pas bloquant seul
JA3 Instabilité GREASE, collisions inter-versions JA4 (GREASE filtré, trié), ratio JA3/JA4 comme feature
JS challenges Contournés par BotBrowser/CloakBrowser Architecture 100 % passive, HTTP/2 fingerprinting
UA matching Trivial à usurper UA est une parmi 96 features, cohérence cross-layer
ML supervisé seul Concept drift, label scarcity Semi-supervisé EIF + AE + retraining adaptatif
Isolation Forest std Ghost clusters en haute dimension Extended Isolation Forest (hyperplans aléatoires)
AE seul Ne détecte pas les anomalies ponctuelles Ensemble EIF + AE complémentaires
Fingerprinting TLS seul Imitable par httpcloak, CloakBrowser Corrélation L5 TLS + L7 HTTP/2 (tls_h2_family_mismatch)
HTTP/2 fingerprinting seul HTTP/1.1 fallback ne produit pas ce signal Dégradation gracieuse : features H2 à 0.5 si HTTP/1.1
Détection par session Flottes distribuées → 1 IP semble normale Graphes bipartis NetworkX (Part B)
Seuil fixe de classification Sur-blocage en période calme, sous-blocage en pic Seuil adaptatif percentile_5 des scores négatifs