Security CVE Watch
1. Quoi ? — Définition et contexte
Section intitulée « 1. Quoi ? — Définition et contexte »Security CVE Watch est un workflow N8N qui scanne quotidiennement les images Docker du VPS à la recherche de vulnérabilités connues (CVE), dédoublonne les détections et n’envoie une alerte que pour les nouveautés ou les escalades de sévérité.
Composants
Section intitulée « Composants »| Workflow | ID | Nodes | Rôle |
|---|---|---|---|
| CVE Watch (parent) | 5mHMlcg2HqEa7pWJ | 18 | Trigger + boucle images + agrégation + notification |
| CVE Scanner (SW-1) | Tz40sFr3CMrw7X81 | 6 | Lance trivy image via SSH sur une image |
| CVE Processor (SW-2) | JCyc4Jkev8fQ1mwL | 9 | Dédup, classification, comparaison historique |
Architecture visuelle
Section intitulée « Architecture visuelle »Périmètre couvert
Section intitulée « Périmètre couvert »Une dizaine d’images de la stack VPS sont scannées : n8nio/n8n, odoo:18, caddy:2-alpine, postgres:16, postgres:17, redis:7-alpine, qdrant/qdrant, crowdsecurity/crowdsec, prom/prometheus, grafana/grafana. La liste est dérivée de docker images --format au runtime, donc les ajouts de stacks sont automatiquement intégrés au prochain scan.
2. Pourquoi ? — Enjeux et motivations
Section intitulée « 2. Pourquoi ? — Enjeux et motivations »Le problème sans veille active
Section intitulée « Le problème sans veille active »Les CVE publiées sur les images Docker ne déclenchent rien automatiquement. Une vulnérabilité critique sur postgres:16 peut traîner des semaines avant d’être remarquée si personne ne consulte explicitement l’avis CVE ou ne lit le changelog du registre.
| Symptôme sans CVE Watch | Cause | Impact |
|---|---|---|
| Vulnérabilité non détectée | Pas de scan systématique | Fenêtre d’exploitation prolongée |
| Faux positifs en boucle | Pas de dédup | Bruit, désensibilisation aux alertes |
| Déclenchement lent | Surveillance manuelle | Aucun mécanisme de relance |
| Pas de traçabilité | Pas d’historique de scan | Impossible de prouver un état |
Pourquoi Trivy plutôt que Snyk ou Docker Scout ?
Section intitulée « Pourquoi Trivy plutôt que Snyk ou Docker Scout ? »| Critère | Trivy | Snyk | Docker Scout |
|---|---|---|---|
| Open source | Oui (Apache 2.0) | Non | Non |
| Self-hosted | Oui | Partiel | Non |
| Sources CVE | NVD, Red Hat, Alpine, Debian, Ubuntu | NVD, Snyk DB | NVD, Snyk DB |
| Auth requise | Non | Token + quota | Docker Hub login |
| Scan offline | Oui (DB locale) | Non | Non |
| Format JSON | Stable, documenté | Stable | Stable |
Le choix de Trivy s’aligne avec la philosophie self-hosted du VPS : pas de dépendance à un SaaS, pas de quota d’API, pas de fuite de la liste des images vers un tiers.
Trois déclencheurs complémentaires
Section intitulée « Trois déclencheurs complémentaires »| Trigger | Fréquence | Cas d’usage |
|---|---|---|
| Cron daily 06:00 | Tous les jours avant la journée | Détecter les CVE publiées la veille |
| Cron weekly Monday 09:00 | Une fois par semaine | Récap hebdomadaire avec tendances |
| DIUN webhook | À chaque pull d’image | Scanner immédiatement une nouvelle version |
Le couplage avec DIUN ferme la boucle : quand DIUN détecte une nouvelle image disponible, le scan CVE est déclenché avant l’approbation Telegram, ce qui permet de refuser un update qui introduirait une régression de sécurité.
3. Comment ? — Mise en œuvre technique
Section intitulée « 3. Comment ? — Mise en œuvre technique »Le parcours d’un scan
Section intitulée « Le parcours d’un scan »1. Inventaire des images — Le parent appelle docker images --format '{{.Repository}}:{{.Tag}}' via SSH local pour obtenir la liste exacte des images chargées sur le VPS au moment du scan.
2. Boucle par image — Pour chacune, le parent appelle le sous-workflow CVE Scanner via Execute Workflow.
3. Scan Trivy — Le Scanner se connecte en SSH au VPS et lance docker exec trivy image --format json --severity CRITICAL,HIGH <image>. Le container trivy est pré-installé et son cache de DB CVE est monté en volume pour éviter de re-télécharger 150 MB à chaque scan.
4. Parsing du résultat — Le Scanner parse le JSON Trivy et retourne un tableau normalisé {cve_id, severity, package, installed, fixed, title, cvss}.
5. Dédup et classification — Le CVE Processor compare chaque finding avec la table cve_notifications. Trois cas :
| Cas | Action |
|---|---|
| CVE inconnue | Insert avec status=new, ajoute à la liste à notifier |
| CVE déjà notifiée | Skip (sauf escalade de sévérité) |
| CVE marquée fixée | Vérifier que le fix est bien appliqué, sinon ré-ouvrir |
6. Agrégation — Le parent regroupe les nouvelles findings par image et par sévérité.
7. Notification — Si au moins une CRITICAL est présente, le parent envoie une alerte immédiate au Notification Hub. Sinon, il attend le passage hebdomadaire pour un digest.
Configuration des Data Tables
Section intitulée « Configuration des Data Tables »cve_notifications (Tfng3e4kUL0Ya4Lm)
Section intitulée « cve_notifications (Tfng3e4kUL0Ya4Lm) »| Colonne | Type | Description |
|---|---|---|
cve_id | string | CVE-YYYY-NNNNN |
image | string | repo:tag |
severity | string | CRITICAL / HIGH / MEDIUM / LOW |
package | string | Paquet vulnérable |
installed_version | string | Version actuelle |
fixed_version | string | Version qui corrige (ou null) |
first_seen | datetime | Première détection |
notified_at | datetime | Date de la dernière notification |
status | string | new / notified / fixed / ignored |
cve_scan_history (elUlUt9HzqSSCr7L)
Section intitulée « cve_scan_history (elUlUt9HzqSSCr7L) »| Colonne | Type | Description |
|---|---|---|
scan_date | datetime | Date du run |
images_scanned | number | Nombre d’images analysées |
critical_count | number | CVE CRITICAL détectées |
high_count | number | CVE HIGH détectées |
report_sent | boolean | Notification envoyée ? |
Format des notifications
Section intitulée « Format des notifications »Alerte immédiate (CRITICAL) envoyée via le Notification Hub :
🚨 CVE CRITIQUE DÉTECTÉE
Image: postgres:16CVE: CVE-2026-12345Severity: CRITICAL (CVSS 9.8)Package: libpqInstalled: 16.2 → Fixed in: 16.3
Stacks affectés:- n8n-stack (n8n-postgres)- odoo-stack (odoo-db)
[🔄 Update maintenant] [📖 Détails CVE] [⏰ Reporter]Digest hebdomadaire envoyé chaque lundi 09:00 :
📊 CVE Watch · Semaine 18
12 scans effectués0 CRITICAL · 3 HIGH · 8 MEDIUM (ignorées)
FIXES APPLIQUÉS:✅ postgres:16.2 → 16.3 (CVE-2026-12345)✅ caddy:2.8.4 → 2.8.5 (CVE-2026-12346)
EN ATTENTE:⏳ redis:7.2.3 → 7.2.4 (planifié dimanche)Intégration avec DIUN
Section intitulée « Intégration avec DIUN »Quand DIUN détecte qu’une nouvelle version d’image est disponible, son webhook déclenche aussi CVE Watch sur cette image spécifique. Le résultat est intégré au message d’approbation Telegram :
| Cas | Bouton de l’approval |
|---|---|
| Nouvelle version sans CVE | [Update] (vert) |
| Nouvelle version + CVE résolue | [Update fixe CVE-XXX] (vert) |
| Nouvelle version + nouvelles CVE | [Update malgré CVE] (orange) |
L’utilisateur prend la décision en pleine conscience du risque.
4. Et si ? — Perspectives et limites
Section intitulée « 4. Et si ? — Perspectives et limites »Limites actuelles
Section intitulée « Limites actuelles »| Limite | Impact | Mitigation |
|---|---|---|
| Lag des feeds CVE | Une CVE publiée hier peut ne pas être encore dans la DB Trivy | Couplage avec abonnement RSS NVD à terme |
| Dépendances applicatives non scannées | Trivy scan les paquets OS, pas les dépendances package.json/requirements.txt à l’intérieur de l’image | Couvrir avec un workflow GitHub Dependabot séparé |
| Pas de scoring contextuel | Un CVSS 9.8 sur un paquet inutilisé reste affiché comme CRITICAL | Whitelist par paquet via error_handling_config-like (à concevoir) |
| Faux positifs sur images musl | Trivy classe parfois des CVE Debian sur des images Alpine (musl) | Ignorer via filtre --ignore-policy Trivy |
Scénarios d’évolution
Section intitulée « Scénarios d’évolution »Si la fréquence quotidienne devient insuffisante :
- Passer à un scan toutes les heures pour les images CRITICAL
- Abonner CVE Watch à un flux NVD quasi-temps-réel
- Coupler avec un webhook Trivy serveur (mode
--server)
Si le bruit de notifications devient gênant :
- Ajouter une whitelist par CVE acceptée (avec justification)
- Regrouper les CVE par paquet plutôt que par CVE
- Ne notifier que si CVSS ≥ 9.0 en mode strict
Si le besoin de conformité émerge :
- Conserver les rapports JSON dans un bucket d’audit
- Générer un PDF mensuel signé
- Exposer une API read-only pour un dashboard externe
Métriques pertinentes
Section intitulée « Métriques pertinentes »| Métrique | Source | Interprétation |
|---|---|---|
cve_critical_open | cve_notifications WHERE status IN ('new','notified') AND severity='CRITICAL' | Doit rester à 0 |
cve_mttr | Δ entre first_seen et fixed_at | Mean Time To Resolution |
scan_failures | cve_scan_history WHERE images_scanned=0 | Indicateur de panne du scanner |
Pages liées
Section intitulée « Pages liées »Infrastructure
Section intitulée « Infrastructure »- Security Stack — Caddy, CrowdSec, Trivy
- Notify Stack — DIUN qui déclenche les scans à chaud
- Architecture VPS — Vue d’ensemble
Workflows
Section intitulée « Workflows »- Notification Hub — Routage des alertes CVE
- Docker Updates — Approval workflow couplé aux scans CVE
- Monitoring Digests — Digest hebdomadaire incluant les CVE
Référence
Section intitulée « Référence »- Glossaire — CVE, CVSS, Trivy