🧠 Machine Learning appliqué aux données textuelles de cybersécurité
Guide expert pour démontrer une compétence concrète dans la classification d’attaques web : SQL Injection, XSS, Command Injection, trafic légitime, logs HTTP/WAF, feature engineering NLP, évaluation SOC, MLOps et intégration SIEM/WAF.
Vision globale ML + Cybersécurité
Construire une expertise crédible : NLP, logs HTTP, attaques web et classification multi-classes.
NLPWAFSOCML SecurityCorpus, logs & données textuelles
Transformer des logs HTTP/WAF hétérogènes en dataset exploitable pour l’apprentissage supervisé.
HTTP logsWAFDatasetLabelingFeature engineering texte
Char n-grams, TF-IDF, tokens sécurité, entropie, longueur et signaux syntaxiques.
TF-IDFn-gramstokensentropyModèles de classification
Comparer modèles linéaires, arbres, boosting et Transformers pour données textuelles de sécurité.
SVMXGBoostBERTEnsembleClassification SQLi / XSS / Command Injection
Comprendre les familles d’attaques, leurs marqueurs textuels et les confusions entre classes.
SQLiXSSCMDiLegitTraining pipeline
Préparation dataset, split temporel, entraînement, calibration et sauvegarde du modèle.
TrainSplitCalibrationArtifactsÉvaluation & métriques SOC
Précision, rappel, F1, faux positifs, coût opérationnel et matrices de confusion.
PrecisionRecallF1SOCExplainability & analyst trust
Rendre les décisions lisibles pour un analyste SOC : tokens, règles, score, contexte.
SHAPTokensSOCTrustÉvasion & robustesse adversariale
Obfuscation, encodage, mutation de payloads et stratégies de défense ML/WAF hybrides.
EvasionObfuscationDriftHardeningInference temps réel & API
Servir le modèle via API, tenir la latence, tracer les décisions et intégrer le dashboard.
FastAPILatencyAPIDashboardMLOps cybersécurité
Versioning, registry, CI/CD modèle, monitoring, rollback et ré-entraînement contrôlé.
MLOpsRegistryCI/CDRollbackIntégration SOC / SIEM / WAF
Passer d’un modèle de classification à une capacité de défense exploitable par les équipes sécurité.
SIEMWAFSOCAlertingGouvernance, RGPD & sécurité modèle
Maîtriser données sensibles, rétention logs, anonymisation, auditabilité et accès modèle.
RGPDPrivacyAuditSecurityProjet portfolio concret
Construire une démonstration crédible : dataset, API, dashboard, métriques et rapport technique.
PortfolioDemoAPIDashboardArgumentaire CV / entretien
Formuler clairement l’expertise : NLP, classification, cybersécurité, MLOps et impact opérationnel.
CVPitchInterviewImpactObjectif professionnel
L’objectif est de démontrer une expertise forte en machine learning appliqué aux données textuelles, avec une capacité concrète à classifier des requêtes HTTP ou des logs applicatifs selon leur nature : trafic légitime, SQL Injection, XSS, Command Injection, path traversal, scanner automatisé, bruit bot ou activité suspecte.
- Comprendre la donnée : requête HTTP brute, URL, headers, payload POST, user-agent, cookies, codes de réponse, taille de réponse, fréquence.
- Comprendre la menace : intention de l’attaquant, vecteur d’entrée, encodage, mutation du payload, bruit de scan.
- Comprendre le modèle : features textuelles, embeddings, seuils de confiance, précision, rappel, dérive.
- Comprendre l’exploitation opérationnelle : alerte SOC, enrichissement SIEM, scoring WAF, priorisation des incidents.
Chaîne de valeur
Classes de classification typiques
| Classe | Signal textuel | Risque | Exploitation modèle |
|---|---|---|---|
| LEGITIMATE | URL normale, paramètres attendus, headers cohérents | Faible | Réduction du bruit, bascule vers allow-score |
| SQL_INJECTION | Fragments SQL, opérateurs logiques, commentaires, union/select | Critique | Blocage ou alerte haute priorité |
| XSS | Balises, handlers JS, encodage HTML/URL suspect | Élevé | Alerte applicative + analyse du paramètre vulnérable |
| COMMAND_INJECTION | Séparateurs shell, commandes système, redirections | Critique | Blocage immédiat, investigation serveur |
| PATH_TRAVERSAL | ../, chemins système, encodages alternatifs | Élevé | Détection d’accès fichiers sensibles |
| SCANNER | User-agent bruité, séquence d’URLs, signature de probing | Moyen à élevé | Corrélation IP / rate-limit / ban temporaire |
Ce que le modèle doit faire
- Classer une requête textuelle avec un niveau de confiance.
- Repérer les signaux faibles et les patterns obfusqués.
- Expliquer quels tokens ou fragments ont pesé dans la décision.
- S’intégrer dans un workflow existant : WAF, SIEM, SOC, dashboard, API.
Ce que le modèle ne doit pas faire seul
- Remplacer toutes les règles WAF : il complète les signatures, il ne les annule pas.
- Bloquer sans garde-fou en production si le coût du faux positif est fort.
- Être entraîné sur des logs contenant des données personnelles non maîtrisées.
- Rester non surveillé : dérive, attaques nouvelles et bruit de logs évoluent.
Architecture logique d’une plateforme de classification d’attaques web
[Nginx / Apache / WAF / CDN]
│
▼
[Log collector] ──► [Parser HTTP] ──► [Normalizer]
│ │
│ ▼
│ [Feature store]
│ │
▼ ▼
[SIEM / Data Lake] [ML classifier API]
│ │
▼ ▼
[Analyst Dashboard] ◄── alerts / labels / confidence / explanationCette architecture permet d’avoir une boucle complète : collecte, classification, explication, feedback analyste, ré-entraînement et supervision de la dérive.
Sources de données utiles
- Access logs Nginx/Apache : méthode, URL, query string, status, user-agent, referer, IP.
- Logs WAF : règle déclenchée, score d’anomalie, payload bloqué, catégorie OWASP CRS.
- Logs applicatifs : route Django/Flask/Node, utilisateur, erreur, stack trace, validation input.
- Proxy/CDN : ASN, pays, réputation IP, taux de requêtes, cache status.
- Datasets publics : utiles pour bootstrap, mais insuffisants sans adaptation au trafic réel.
Structure minimale d’un exemple
{
"method": "GET",
"path": "/search",
"query": "q=react+developer",
"headers": {"user-agent": "Mozilla/5.0"},
"status": 200,
"body_sample": "",
"label": "LEGITIMATE"
}Nettoyer sans détruire les signaux d’attaque
La normalisation est délicate : trop faible, le modèle apprend des variantes inutiles ; trop forte, on efface les indices de compromission.
| Traitement | Objectif | Risque si mal fait |
|---|---|---|
| URL decoding | Révéler les payloads encodés | Double décodage destructeur |
| Lowercase contrôlé | Réduire la variance | Perdre une information sur certains tokens |
| Remplacement chiffres | Éviter l’overfit sur des IDs | Effacer un port, une version ou un chemin significatif |
| Conservation ponctuation | Garder les signaux SQL/shell/JS | Une tokenisation trop classique supprime le signal |
from urllib.parse import unquote_plus
import re
def normalize_http_text(value: str) -> str:
value = unquote_plus(value or "")
value = value.replace("\x00", " ")
value = re.sub(r"\s+", " ", value)
return value.strip()Labeling supervisé
La qualité des labels est le facteur déterminant. En sécurité, les labels proviennent souvent d’un mélange : règles WAF, analystes SOC, honeypots, tests contrôlés, corpus publics et feedback post-incident.
- Label principal : catégorie de menace dominante.
- Label secondaire : technique observée, famille, règle WAF, route cible.
- Confiance label : humain validé, règle forte, règle faible, heuristique.
- Source label : WAF, analyste, sandbox, dataset public.
Schéma dataset recommandé
id, raw_text, normalized_text, label, label_confidence, source, route, status, timestamp, analyst_feedback 1, "GET /?q=test", "GET /?q=test", LEGITIMATE, 0.95, nginx, search, 200, 2026-07-06T09:10:00Z, confirmed
Éviter les faux bons scores
Un modèle peut afficher un F1-score spectaculaire tout en étant inutile en production s’il a appris des artefacts de dataset plutôt que des signaux d’attaque.
| Fuite | Exemple | Correction |
|---|---|---|
| Route artificielle | Tous les XSS viennent de /test/xss | Split par source et par période |
| IP ou user-agent | Une IP de test identifie toutes les attaques | Masquer ou agréger les marqueurs faibles |
| Payload dupliqué | Même attaque présente en train et test | Déduplication par hash normalisé |
| Temps | Dataset attaque collecté un seul jour | Validation temporelle |
Pourquoi les n-grams caractères sont puissants
Les attaques web sont souvent reconnaissables à des fragments très courts : opérateurs, séparateurs, encodages, ponctuation, balises, mots-clés SQL ou shell. Les char n-grams capturent ces micro-signaux mieux qu’une tokenisation NLP classique.
- Robustes aux fautes, mutations, encodages partiels.
- Très efficaces avec TF-IDF + Linear SVM / Logistic Regression.
- Adaptés aux URLs, query strings, headers et payloads courts.
Pipeline classique
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import Pipeline
pipeline = Pipeline([
("tfidf", TfidfVectorizer(
analyzer="char_wb",
ngram_range=(3, 6),
min_df=2,
sublinear_tf=True
)),
("clf", LogisticRegression(max_iter=2000, class_weight="balanced"))
])Features spécialisées cyber
| Feature | Signal | Classes concernées |
|---|---|---|
| special_char_ratio | Proportion de caractères non alphanumériques | SQLi, XSS, command injection |
| url_encoding_count | Occurrences de %xx, double encodage | Toutes attaques obfusquées |
| keyword_sql_count | select, union, where, sleep, benchmark | SQL Injection |
| html_tag_count | Fragments <tag>, attributes, handlers | XSS |
| shell_separator_count | ;, |, &&, backticks, redirections | Command Injection |
| path_depth_score | ../, chemins absolus, normalisation chemin | Traversal / LFI |
def security_features(text: str) -> dict:
lower = text.lower()
return {
"len": len(text),
"special_ratio": sum(not c.isalnum() for c in text) / max(len(text), 1),
"url_encoding_count": lower.count("%"),
"sql_keywords": sum(k in lower for k in ["select", "union", "where", "sleep"]),
"xss_markers": sum(k in lower for k in ["Combiner texte vectorisé et features numériques
Le meilleur compromis industriel est souvent hybride : TF-IDF char n-grams pour le signal textuel + features numériques de sécurité pour stabiliser la décision.
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.svm import LinearSVC
features = ColumnTransformer([
("text", TfidfVectorizer(analyzer="char", ngram_range=(3, 5)), "normalized_text"),
("num", StandardScaler(), ["len", "special_ratio", "url_encoding_count"]),
])
model = Pipeline([
("features", features),
("clf", LinearSVC(class_weight="balanced"))
])Pièges fréquents
- Tokenisation NLP standard : souvent mauvaise pour des payloads où la ponctuation est le signal principal.
- Suppression de caractères spéciaux : détruit la différence entre requête légitime et injection.
- Stemming / lemmatisation : peu utile et parfois destructeur sur logs techniques.
- Features uniquement lexicales : insuffisant contre la mutation, l’encodage et le bruit applicatif.
- Features trop expertes : peuvent surapprendre des signatures connues et rater des variantes.
Baselines recommandées
| Modèle | Avantages | Limites | Usage |
|---|---|---|---|
| Logistic Regression | Rapide, proba, explicable | Frontière linéaire | Baseline production |
| Linear SVM | Très fort sur TF-IDF sparse | Probabilités indirectes | Classification haute précision |
| Random Forest | Gère features numériques | Moins fort sur texte sparse massif | Features expertes |
| XGBoost / LightGBM | Très bon avec features hybrides | Tuning nécessaire | Score final tabulaire + texte réduit |
| Transformer | Contexte, sémantique, généralisation | Coût, latence, monitoring | Cas avancé / modèle expert |
Quand utiliser un Transformer ?
Les Transformers deviennent intéressants lorsque les données contiennent du contexte long : headers complets, logs multi-lignes, messages d’erreur, corps JSON, séquences de requêtes, traces applicatives ou corrélation de plusieurs champs.
- DistilBERT : bon compromis latence/performance.
- CodeBERT / modèles code : utiles si les payloads ressemblent à du code, SQL, JS ou shell.
- Longformer-like : pertinent pour logs très longs, mais plus coûteux.
Input enrichi
[METHOD] GET [PATH] /search [QUERY] q=<payload> [UA] Mozilla/5.0 [STATUS] 403 [ROUTE] search_view [WAF_SCORE] 8
Structurer l’entrée par champs aide le modèle à apprendre le contexte sans mélanger tous les signaux.
Architecture ensemble robuste
Un ensemble permet de combiner la précision des règles fortes, la robustesse des n-grams, l’expressivité des features expertes et la compréhension contextuelle d’un modèle profond.
| Signal | Poids opérationnel | Action |
|---|---|---|
| Règle WAF critique + ML haute confiance | Très élevé | Blocage / incident P1 |
| ML haute confiance seul | Élevé | Alerte SOC + enrichissement |
| ML faible confiance | Moyen | Observation / feedback |
| Règle faible seule | Variable | Corrélation avec historique IP/session |
Recommandation pragmatique
TF-IDF char n-grams + Logistic Regression. Rapide, lisible, excellent baseline.
Ajout features sécurité + calibration seuils + explainability.
Transformer léger pour les cas ambigus et analyse contextuelle longue.
Signaux SQL Injection
- Opérateurs booléens suspects dans paramètres texte.
- Mots-clés SQL proches de séparateurs ou commentaires.
- Fonctions temporelles ou d’erreur utilisées comme oracle.
- Encodage URL ou casse mixte pour contourner des filtres simples.
Le modèle doit distinguer un mot légitime comme “select” dans une documentation d’un contexte réellement malveillant.
Exemples défensifs de signaux
label = "SQL_INJECTION" examples = [ "id=10 union select ...", "q=' or '1'='1", "search=test%27%20or%201%3D1" ]
Signaux Cross-Site Scripting
| Signal | Exemple de marqueur | Attention |
|---|---|---|
| Balise HTML | <script>, <img>, <svg> | Peut être légitime dans un CMS ou éditeur HTML |
| Handler JS | onerror, onload, onclick | À croiser avec contexte champ |
| Schéma suspect | javascript: | Souvent fort indicateur |
| Encodage | <, %3C, unicode escape | Normaliser sans effacer |
Signaux Command Injection
- Séparateurs de commandes : point-virgule, pipe, doubles opérateurs.
- Références à chemins système, variables shell, redirections.
- Commandes utilitaires souvent observées dans des probes.
- Payloads courts mais très ponctués.
La Command Injection se confond parfois avec du bruit shell dans des logs techniques. Le contexte route/paramètre est essentiel.
Feature logique
def looks_like_command_injection(text):
markers = [";", "&&", "||", "|", "$(", "`", ">", "<"]
shell_words = ["sh", "bash", "cmd", "powershell", "whoami"]
lower = text.lower()
return sum(m in lower for m in markers) >= 2 or any(w in lower for w in shell_words)Le plus difficile : reconnaître le normal
La classe LEGITIMATE n’est pas une poubelle. Elle doit couvrir les vrais usages métier : recherche, formulaires, back-office, APIs JSON, éditeurs HTML, exports, filtres avancés, contenu utilisateur.
| Cas légitime | Risque de faux positif | Contre-mesure |
|---|---|---|
| Recherche contenant des mots techniques SQL | SQLi | Contexte route + tokens environnants |
| CMS autorisant HTML | XSS | Rôle utilisateur + champ autorisé |
| Documentation shell | Command Injection | Route documentation / markdown |
| API JSON avec caractères spéciaux | Injection générique | Parsing JSON + schéma attendu |
Workflow d’entraînement robuste
def train_release(dataset):
dataset = normalize(dataset)
dataset = deduplicate_by_hash(dataset)
train, valid, test = temporal_split(dataset)
model = fit_pipeline(train)
metrics = evaluate(model, valid, test)
if metrics["recall_ATTACK"] >= 0.95 and metrics["fp_rate"] <= 0.01:
register_model(model, metrics)
return metricsPourquoi le split aléatoire ne suffit pas
En cybersécurité, les campagnes d’attaque arrivent par vagues. Un split aléatoire peut mettre le même payload ou la même campagne dans train et test, ce qui gonfle artificiellement les scores.
| Split | Qualité | Usage |
|---|---|---|
| Random split | Faible à moyen | Debug rapide uniquement |
| Temporal split | Fort | Simulation production |
| Source split | Fort | Tester généralisation sur nouvelle app |
| Payload-family split | Très fort | Tester robustesse à variantes inédites |
Seuils et décisions
La sortie brute d’un modèle n’est pas automatiquement une décision de blocage. Il faut définir des seuils par classe, selon le coût métier.
- Seuil SQLi : très sensible si risque critique.
- Seuil XSS : à ajuster si l’application autorise HTML.
- Seuil LEGITIMATE : utile pour réduire le bruit SOC.
- Zone grise : envoyer en revue analyste plutôt que bloquer.
Decision policy
if proba["SQL_INJECTION"] > 0.98:
action = "block"
elif max(proba.values()) < 0.65:
action = "review"
elif proba["LEGITIMATE"] > 0.90:
action = "allow"
else:
action = "alert"Versionner tout ce qui influence le résultat
- Code de normalisation.
- Vectorizer TF-IDF / tokenizer.
- Modèle entraîné.
- Mapping labels.
- Seuils de décision.
- Dataset hash, date, source, distribution des classes.
- Rapport métriques et matrice de confusion.
model_artifact/ model.joblib vectorizer.joblib label_mapping.json thresholds.json metrics.json train_manifest.json normalization_version.txt
Métriques essentielles
| Métrique | Interprétation sécurité | Point d’attention |
|---|---|---|
| Precision | Parmi les alertes, combien sont réellement malveillantes ? | Impact direct sur fatigue analyste |
| Recall | Parmi les attaques, combien sont détectées ? | Critique pour attaques graves |
| F1-score | Équilibre precision/recall | Peut masquer les classes rares |
| False Positive Rate | Trafic légitime bloqué ou alerté | Très coûteux en production |
| PR-AUC | Qualité sur classes déséquilibrées | Plus utile que ROC-AUC si peu d’attaques |
Lire une matrice de confusion en sécurité
La matrice ne sert pas seulement à vérifier un score global. Elle révèle les confusions dangereuses : SQLi classée légitime, XSS classé contenu HTML normal, scanner classé trafic humain.
from sklearn.metrics import classification_report, confusion_matrix
pred = model.predict(X_test)
print(classification_report(y_test, pred, digits=3))
print(confusion_matrix(y_test, pred, labels=[
"LEGITIMATE", "SQL_INJECTION", "XSS", "COMMAND_INJECTION"
]))Coût des erreurs
| Erreur | Conséquence | Stratégie |
|---|---|---|
| Faux positif sur login client | Blocage utilisateur / perte business | Seuil plus haut + revue contextuelle |
| Faux négatif SQLi | Risque compromission DB | Seuil bas + règles fortes en complément |
| XSS détecté comme SQLi | Catégorie fausse mais alerte utile | Acceptable si action conservatrice |
| Scanner classé légitime | Bruit de reconnaissance invisible | Corrélation comportementale par IP/session |
Validation par jeux de tests adversariaux contrôlés
- Payloads encodés URL une ou deux fois.
- Variations de casse, espaces, commentaires, caractères Unicode.
- Longue query string contenant un signal malveillant faible.
- Trafic légitime contenant HTML/SQL/shell dans un contexte documentaire.
- Requêtes multi-paramètres où seul un champ est suspect.
Pourquoi expliquer ?
Un score seul n’est pas exploitable. L’analyste doit comprendre rapidement pourquoi une requête est classée malveillante : fragment déclencheur, champ concerné, classe probable, niveau de confiance, historique IP et décision recommandée.
Probabilité ou marge de décision par classe.
Tokens ou n-grams qui ont pesé dans la décision.
Route, IP, fréquence, règle WAF, status HTTP.
Explication simple avec modèle linéaire
Avec TF-IDF + Logistic Regression, les poids du modèle permettent d’identifier les n-grams associés à chaque classe.
def top_class_terms(vectorizer, classifier, class_name, n=20):
class_id = list(classifier.classes_).index(class_name)
weights = classifier.coef_[class_id]
names = vectorizer.get_feature_names_out()
top = weights.argsort()[-n:][::-1]
return [(names[i], float(weights[i])) for i in top]Format d’alerte SOC recommandé
{
"prediction": "SQL_INJECTION",
"confidence": 0.992,
"action": "alert_high",
"evidence": ["union", "select", "--", "%27"],
"field": "query_string",
"route": "/search",
"source_ip_risk": "medium",
"waf_rule": "crs-942100",
"model_version": "webattack-clf-2026.07.1"
}Boucle de feedback
- L’analyste confirme ou corrige la classe.
- Le système stocke l’échantillon, l’explication et la version du modèle.
- Les corrections alimentent un buffer de ré-entraînement.
- Les faux positifs critiques déclenchent une revue de seuil ou de feature.
feedback = {
"request_id": "req_20260706_001",
"model_prediction": "XSS",
"analyst_label": "LEGITIMATE",
"reason": "CMS editor allows HTML for admin role",
"priority": "high"
}Ce que cherchent les attaquants
Les attaquants modifient la forme textuelle d’un payload pour contourner signatures et modèles : encodage, commentaires, casse, séparation de tokens, caractères Unicode, bruit ajouté, variantes syntaxiques.
| Technique | Effet sur modèle naïf | Défense |
|---|---|---|
| Encodage URL/HTML | Signal masqué | Décodage contrôlé + features encodage |
| Insertion bruit | n-grams perturbés | N-grams multi-tailles + normalisation |
| Variation casse | Token exact raté | Lowercase contrôlé + features originales |
| Payload très long | Signal noyé | Fenêtrage, max suspicious segment |
Stratégies de robustesse
- Normalization ensemble : prédire sur version brute, décodée, nettoyée et segmentée.
- Data augmentation défensive : variantes contrôlées sur données d’entraînement.
- Hybridation règles + ML : les règles fortes capturent certains invariants.
- Détection de faible confiance : orienter vers revue humaine.
- Monitoring de drift : observer l’apparition de nouveaux tokens et patterns.
def predict_robust(model, raw_text):
variants = [
raw_text,
normalize_http_text(raw_text),
normalize_http_text(normalize_http_text(raw_text)),
suspicious_window(raw_text)
]
scores = [model.predict_proba([v])[0] for v in variants]
return aggregate_scores(scores)Surveiller la dérive
La dérive peut venir du trafic légitime qui change, de nouvelles routes applicatives, d’une campagne de scan, d’un nouveau framework JS ou de techniques d’attaque émergentes.
| Signal de dérive | Symptôme | Action |
|---|---|---|
| Hausse inconnus/faible confiance | Modèle moins sûr | Échantillonnage revue analyste |
| Top tokens nouveaux | Nouveaux patterns | Analyse menace + enrichissement dataset |
| Faux positifs sur route récente | Changement applicatif | Contextualiser route/champ |
| Distribution classes change | Campagne d’attaque ou bug | Corrélation logs WAF/SIEM |
Garde-fous production
- Mode shadow avant blocage réel.
- Blocage seulement si modèle + règle forte + seuil haut.
- Allow-list contextuelle pour routes métier connues.
- Rollback rapide du modèle si faux positifs massifs.
- Journaliser version modèle, seuils et explication à chaque décision.
API de classification
L’API reçoit une requête normalisée, calcule la prédiction et retourne une décision structurée exploitable par dashboard, WAF ou SIEM.
- Endpoint synchrone pour décision rapide.
- Batch endpoint pour ré-analyse de logs historiques.
- Journalisation systématique des prédictions.
FastAPI minimal
from fastapi import FastAPI
from pydantic import BaseModel
import joblib
app = FastAPI()
model = joblib.load("model.joblib")
class RequestText(BaseModel):
text: str
route: str | None = None
@app.post("/classify")
def classify(req: RequestText):
text = normalize_http_text(req.text)
pred = model.predict([text])[0]
return {"label": pred, "model_version": "2026.07.1"}Budget de latence
| Composant | Objectif | Optimisation |
|---|---|---|
| Parsing / normalisation | < 2 ms | Fonctions simples, pas d’I/O |
| TF-IDF + modèle linéaire | < 10 ms | Modèle chargé en mémoire |
| Transformer | 20-200 ms | Batching, distillation, GPU optionnel |
| Logging décision | Asynchrone | Queue, Kafka, Redis, Celery |
Intégration dans un dashboard Django
# views.py - exemple simplifié
from django.http import JsonResponse
@require_POST
def classify_payload(request):
raw = request.POST.get("payload", "")
result = cyber_ml_classifier.predict(raw)
return JsonResponse({
"label": result.label,
"confidence": result.confidence,
"evidence": result.evidence,
"action": result.action,
})Le résultat peut alimenter une modale d’explication, un tableau de logs, un score de risque ou une action de quarantaine.
Tracer chaque décision
| Champ | Pourquoi |
|---|---|
| request_hash | Déduplication et preuve sans stocker tout le payload |
| label / confidence | Audit de décision |
| model_version | Reproductibilité |
| threshold_policy | Comprendre l’action prise |
| evidence | Explication analyste |
| feedback_status | Boucle de correction |
Model registry
Chaque modèle doit être enregistré avec ses métriques, son dataset source, sa version de code, ses seuils et son statut de déploiement.
model_registry:
name: web_attack_text_classifier
version: 2026.07.1
status: staging
training_data_hash: sha256:...
metrics:
macro_f1: 0.962
recall_sql_injection: 0.984
recall_command_injection: 0.971
false_positive_rate_legitimate: 0.006
thresholds:
SQL_INJECTION: 0.96
XSS: 0.94
COMMAND_INJECTION: 0.97Pipeline CI/CD modèle
- Tests sur payloads connus et faux positifs historiques.
- Validation des métriques minimales par classe.
- Comparaison nouveau modèle vs modèle production.
- Déploiement shadow avant activation.
Monitoring production
| Indicateur | Seuil d’alerte | Action |
|---|---|---|
| Taux de faible confiance | Hausse brutale | Analyse drift |
| Distribution des classes | Pic anormal SQLi/XSS | Corrélation campagne |
| Faux positifs analystes | > seuil métier | Rollback ou ajustement seuil |
| Latence p95 | Dépasse budget | Scaling ou modèle plus léger |
| Erreurs API | Spike 5xx | Fallback règles WAF |
Plan de rollback
- Conserver les deux dernières versions stables en mémoire ou stockage local.
- Séparer version modèle et seuils de décision.
- Activer un kill-switch pour repasser en mode alerte seule.
- Tracer la cause : métrique, incident, faux positif, erreur API.
if incident.fp_rate_high or api_error_rate > 0.02:
deployment.set_mode("shadow")
deployment.activate_model("previous_stable")
notify_soc("ML classifier rollback executed")Enrichir les événements SIEM
Le modèle ajoute une couche sémantique à des logs parfois très bruts. L’événement SIEM devient plus exploitable : catégorie ML, confiance, tokens explicatifs, action recommandée.
cef:0|IdeoLab|CyberML|1.0|WEB_ATTACK|ML Web Attack Classification|8| src=203.0.113.10 request=/search?q=... ml_label=SQL_INJECTION ml_confidence=0.992 ml_action=alert_high model=2026.07.1
Complémentarité WAF + ML
| WAF règles | ML texte | Combinaison |
|---|---|---|
| Très précis sur signatures connues | Généralise sur variantes | Réduction faux négatifs |
| Explication règle claire | Explication tokens/statistique | Meilleure investigation |
| Peut être contourné par mutation | Peut dériver ou se tromper | Décision hybride robuste |
Dashboard analyste
- Liste des requêtes classées avec filtre par classe et confiance.
- Vue détail : payload, champ, route, tokens importants.
- Historique IP/session : nombre de hits, pays, ASN, user-agent.
- Boutons feedback : correct / incorrect / classe réelle.
- Export CSV/JSON pour investigation.
Actions recommandées par classe
| Classe | Action immédiate | Investigation |
|---|---|---|
| SQL_INJECTION | Alerte haute / blocage si seuil fort | Vérifier logs DB, erreurs 500, endpoints vulnérables |
| XSS | Alerte applicative | Identifier champ reflété/stocké, rôle utilisateur |
| COMMAND_INJECTION | Critique | Logs système, process spawn, EDR serveur |
| SCANNER | Rate limit / ban temporaire | Corréler IP, ASN, séquence URLs |
Données sensibles dans les logs
Les logs HTTP peuvent contenir emails, tokens, cookies, identifiants, paramètres personnels ou données métier. Un pipeline ML doit intégrer privacy et sécurité dès la conception.
| Donnée | Risque | Mesure |
|---|---|---|
| IP source | Donnée personnelle potentielle | Pseudonymisation ou agrégation |
| Cookie/session | Secret d’accès | Suppression ou hash salé |
| Query string | PII ou secrets | Masquage champs sensibles |
| Body POST | Données utilisateur | Échantillonnage, minimisation |
Rétention et minimisation
- Stocker le payload brut uniquement si nécessaire à l’investigation.
- Préférer hash + fragments explicatifs lorsque possible.
- Définir une durée de conservation par type de donnée.
- Séparer logs opérationnels, dataset d’entraînement et preuves incident.
- Documenter les bases légales et les finalités.
Protéger le modèle
- Limiter l’accès à l’API de prédiction.
- Rate-limit pour éviter l’extraction comportementale du modèle.
- Journaliser les requêtes de classification.
- Ne pas exposer les poids ou les features complètes à des utilisateurs non autorisés.
- Signer les artifacts modèle et contrôler leur intégrité.
Auditabilité
audit_record = {
"decision_id": "mlsec-20260706-0001",
"timestamp": "2026-07-06T10:15:00Z",
"input_hash": "sha256:...",
"model_version": "2026.07.1",
"threshold_policy": "prod-high-sensitivity-v3",
"prediction": "SQL_INJECTION",
"confidence": 0.992,
"action": "alert_high"
}Projet démonstrateur
Construire une application qui prend des requêtes HTTP ou des logs Nginx en entrée, détecte la classe probable d’attaque, explique la décision et affiche les résultats dans un dashboard.
Django ou FastAPI pour ingestion et prédiction.
Pipeline sklearn + modèle versionné.
Dashboard avec cartes, filtres, modales et feedback.
Modules à prévoir
| Module | Responsabilité |
|---|---|
| log_parser.py | Parser access logs et extraire champs HTTP |
| normalizer.py | Décodage et nettoyage contrôlé |
| features.py | Features sécurité numériques |
| train_model.py | Entraînement et sauvegarde artifacts |
| classifier_service.py | Chargement modèle et prédiction |
| views.py | Dashboard, API classify, feedback analyste |
Dashboard attendu
- Carte globale : nombre de requêtes analysées, attaques détectées, taux de confiance moyen.
- Répartition par classe : SQLi, XSS, Command Injection, Legitimate.
- Table des événements avec filtres par classe/seuil/IP/route.
- Modale détail : texte brut, normalisé, prédiction, évidence, action.
- Bouton feedback pour corriger le label.
Ce qu’il faut documenter
- Problème traité et contexte cybersécurité.
- Classes de menace et exemples de signaux.
- Pipeline ML : normalisation, features, modèle, métriques.
- Résultats : matrice de confusion, faux positifs, limites.
- Architecture : API, dashboard, intégration SIEM/WAF possible.
- Gouvernance : anonymisation, versioning, monitoring.
Pitch court
Pitch technique
Formulations CV
- Conception d’un pipeline de classification ML/NLP pour détecter les attaques web dans des logs HTTP et WAF.
- Feature engineering avancé sur payloads textuels : char n-grams, TF-IDF, signaux d’encodage, tokens SQL/JS/shell et métriques de suspicion.
- Classification multi-classes : trafic légitime, SQL Injection, XSS, Command Injection, path traversal et scans automatisés.
- Évaluation orientée cybersécurité : recall par classe critique, faux positifs métier, matrice de confusion et tests adversariaux.
- Industrialisation MLOps : versioning modèle, API d’inférence, monitoring de drift, feedback analyste et intégration SIEM/WAF.
Questions possibles en entretien
| Question | Réponse attendue |
|---|---|
| Pourquoi char n-grams ? | Parce que les attaques web contiennent des micro-signaux syntaxiques où ponctuation et fragments courts sont déterminants. |
| Comment limiter les faux positifs ? | Seuils par classe, contexte route/champ, feedback analyste, mode shadow, validation métier. |
| Pourquoi ne pas tout faire avec BERT ? | Coût/latence/explicabilité ; un baseline TF-IDF linéaire est souvent très fort et plus simple à industrialiser. |
| Comment gérer l’évasion ? | Normalisation multiple, data augmentation défensive, tests adversariaux, monitoring de drift, hybridation WAF + ML. |
Positionnement senior
- Ne pas vendre seulement un modèle, mais une capacité complète de détection exploitable.
- Insister sur le compromis sécurité / faux positifs / latence / explicabilité.
- Relier ML à SOC, SIEM, WAF, dashboard et remédiation.
- Montrer une compréhension des attaques, pas uniquement des algorithmes.
- Parler de monitoring et de dérive : un modèle cyber n’est jamais fini.
