Quand spaCy ne voit pas l'infrastructure : le problème NLP des logs de sécurité
Quand spaCy ne voit pas l’infrastructure : le problème NLP des logs de sécurité
Avant d’envoyer des logs à un éditeur de logiciels pour investigation, à un LLM externe pour analyse, ou simplement de les archiver conformément au RGPD, une question s’impose : ces logs contiennent-ils des informations qui exposent mon infrastructure ?
La réponse est presque toujours oui. Et les outils NLP standards — aussi performants soient-ils sur le langage courant — sont largement aveugles aux entités spécifiques au domaine de la sécurité.
Le problème : deux types de PII, une seule couche de protection inadaptée
Le RGPD définit les données personnelles (PII) : noms, adresses, emails, numéros de téléphone. Les outils comme spaCy fr_core_news_lg ou ses équivalents anglophones sont entraînés pour les détecter dans du texte courant — articles de presse, documents RH, courriels.
Les logs de sécurité exposent un second type d’information, orthogonal : l’infrastructure interne. Ces données ne sont pas des données personnelles au sens du RGPD, mais leur divulgation peut compromettre la sécurité du système d’information.
Mar 4 09:14:22 srv-dc01.corp.local sshd[3847]: Failed password for svc_splunk_admin from 192.168.10.50 port 52341 ssh2
Dans ce log syslog :
srv-dc01.corp.local— nom du contrôleur de domaine internesvc_splunk_admin— compte de service Splunk avec probablement des droits élevés192.168.10.50— IP interne, potentiellement un poste attaquant ou compromis
spaCy ne détecte aucune de ces trois entités.
Ce que spaCy rate dans les logs de sécurité
Le tableau ci-dessous résume les entités sensibles typiques d’une infrastructure sécurité, avec leur comportement face à un modèle NLP standard :
| Entité | Exemple réel | spaCy | Raison du ratage |
|---|---|---|---|
| Hostname interne | srv-dc01.corp.local |
✗ | Ressemble à une URL, pas à un nom propre |
| Compte de service | svc_splunk_admin |
✗ | Pattern technique, hors corpus d’entraînement |
| Règle firewall | ALLOW_RDP_FROM_VPN_192.168.10.0 |
✗ | Chaîne composée, aucun contexte dans le corpus |
| Subnet interne | 10.10.42.0/24 |
✗ | IP détectée partiellement, CIDR jamais |
| Community SNMP | corp-monitoring |
✗ | Ambigu — label générique ou credential ? |
| Username VPN | jdoe@corp |
partiel | Format email détecté, domaine interne ignoré |
| CVE lié à un asset | CVE-2024-12345 sur srv-web01 |
✗ | CVE ignoré, hostname ignoré |
| Adresse MAC | 00:1A:2B:3C:4D:5E |
✗ | Hors corpus |
| Numéro de port | port 52341 |
✗ | Nombre, sans sémantique |
Ce n’est pas un défaut de spaCy — c’est un problème de distribution. Ces modèles sont entraînés sur des corpus de presse et de texte général. Les logs de sécurité constituent un domaine entièrement différent, avec sa propre syntaxe, ses conventions de nommage, et ses patterns d’entités.
La difficulté supplémentaire : la décision contextuelle
Détecter une entité ne suffit pas. Il faut aussi décider comment la remplacer, et cette décision dépend du contexte.
Prenons trois adresses IP dans le même batch de logs :
192.168.1.254 → IP interne critique (gateway) → remplacer par IP fictive cohérente
8.8.8.8 → serveur DNS public connu → REDACTED ou conserver selon contexte
203.0.113.10 → IP externe d'un attaquant connu → conserver si le rapport d'incident l'exige
La stratégie de remplacement optimale change selon la destination du log :
| Destination | Stratégie privilégiée | Réversibilité |
|---|---|---|
| Éditeur logiciel (support) | Token séquentiel lisible (IP_001, HOST_001) |
Oui |
| LLM externe (Claude API, GPT) | Faker cohérent (IPs fictives mais crédibles) | Non |
| Archivage RGPD/ANSSI | REDACTED ou token + mapping UUID chiffré | Oui |
| Audit humain externe | Token séquentiel explicite | Oui |
Un NER classique ne peut pas prendre ces décisions — il détecte, il ne raisonne pas.
L’architecture à deux couches
Face à ces contraintes, une séparation claire des responsabilités s’impose :
graph TD
A[Logs bruts] --> B[AnonyNER\nNER sécurité]
B --> C[Inventaire d'entités\npar fichier]
C --> D[LLM local\nConsolidation]
D --> E[Mapping unifié\ntoken séquentiel]
E --> F[anonyfiles\nMoteur de remplacement]
F --> G[Logs anonymisés]
F --> H[Mapping réversible\nchiffré]
Couche moteur — anonyfiles (fork) : gère la détection de base (PER, LOC, ORG, EMAIL, PHONE), les stratégies de remplacement, la réversibilité via mapping UUID, les formats multiples (txt, JSON, CEF, syslog).
Couche cerveau — AnonyAgent (cyber-agent-engine) : pilote l’orchestration — décide quoi soumettre, avec quelle stratégie, résout les aliases cross-fichiers, gère la cohérence sur tout un batch.
Cette séparation permet à chaque couche d’évoluer indépendamment. Les améliorations NER sécurité dans le fork anonyfiles peuvent être soumises en contribution upstream. La logique de décision dans AnonyAgent reste spécifique à l’environnement opérationnel.
Les trois approches NER comparées
Pour couvrir les entités manquantes, trois niveaux d’investissement sont possibles :
| Approche | Effort | Délai prod | Qualité | Adapté à |
|---|---|---|---|---|
Regex dans custom_rules_processor |
~1 jour | Immédiat | HOSTNAME, IP/CIDR, CVE, svc_* bien couverts |
Entités à syntaxe fixe |
| spaCy NER fine-tuné (corpus LLM-annoté) | ~1 semaine | Après labelling | Meilleure généralisation, <5 ms, sans GPU | Entités contextuelles ambiguës |
| LoRA NER — Phi-3.5-mini | ~3 semaines | Long | Meilleure généralisation, GPU requis | Volume et diversité élevés |
Les regex couvrent ~80% des cas : les formats de sécurité sont largement définis (192.168.x.x/CIDR, CVE-YYYY-NNNNN, svc_*, ALLOW_*/DENY_*). Le fine-tuning spaCy n’apporte de la valeur que pour les entités contextuelles — distinguer corp-monitoring (community SNMP sensible) de corp-monitoring (label générique dans un email).
L’approche hybride recommandée : utiliser un LLM pour annoter automatiquement des logs bruts réels, puis fine-tuner spaCy sur ce corpus :
LLM (Claude / Phi-3.5-mini)
→ annote automatiquement des logs réels
→ produit corpus annoté (~5 000 exemples)
↓
spaCy NER fine-tuné sur le corpus
→ modèle léger (~50 Mo)
→ inférence <5 ms, sans GPU
→ intégrable directement dans anonyfiles
Le LLM crée les données. spaCy fait l’inférence en production. Les deux ne sont pas concurrents — ils sont complémentaires.
Pourquoi ce projet maintenant
Deux pressions réglementaires convergent :
RGPD — l’obligation de traiter les données personnelles s’étend aux logs dès qu’ils contiennent des informations permettant d’identifier des personnes physiques (comptes nominatifs, adresses IP soumises à la jurisprudence Breyer).
DORA (Digital Operational Resilience Act, applicable aux entités financières depuis janvier 2025) — impose des exigences de traçabilité et de transmission sécurisée d’informations aux régulateurs, avec des garanties sur la non-divulgation de l’infrastructure.
Au-delà du cadre légal, le cas d’usage le plus immédiat est pragmatique : envoyer des logs à un éditeur de logiciels pour investigation. Ces logs ne doivent pas exposer l’infrastructure interne au tiers — mais ils doivent rester cohérents et corrélables pour que le support technique puisse travailler dessus.
La suite de cette série
Les articles suivants détaillent chaque composant de ce pipeline :
- Article 2 — Où trouver des logs non anonymisés pour entraîner un agent : LogHub, SDLog, CIC-IDS, logs synthétiques
- Article 3 — Fine-tuner spaCy sur les entités de sécurité : 12 labels, 4 920 exemples JSONL, pipeline de production
- Article 4 — Attaques de ré-identification sur logs anonymisés : la méthode Recollect & Rank et comment s’en prémunir
- Article 5 — Cohérence inter-fichiers : la session de remplacement partagée et l’architecture trois étapes
Ressources :
