đĄïž SENTRY â Bilan M7 « Production Hardening », lot 2¶
Date : 04/10/2026 · Branche : feature/m7-production-hardening (lots 1 et 2) ·
Décision : ADR-012 (proposé)
Verdict : la limite principale du lot 1 est levée : l'application ne possÚde plus ses tables
et ne peut plus altĂ©rer la structure, l'audit ni la chronologie, mĂȘme compromise. Les sessions
sont révocables. M7 reste ouvert sur le lot 3 (TLS, scan d'image, déploiement).
1. Ce qui a Ă©tĂ© rejouĂ© depuis le lot 1¶
| Opération non faite le 03/10 | Résultat le 04/10 |
|---|---|
| Construction de l'image Docker | â
construite et exĂ©cutĂ©e en production (migrations par le propriĂ©taire, API en rĂŽle applicatif, /ready vert, HSTS, /docs masquĂ©, UID 10001, pas d'en-tĂȘte Server). Docker Hub, GHCR, ECR et le miroir Google Ă©tant bloquĂ©s depuis le bac Ă sable, la base python:3.12-slim a Ă©tĂ© remplacĂ©e localement par Ubuntu 24.04 + CPython 3.12 ; le Dockerfile, lui, est inchangĂ©. |
| NVD (API) | â toujours bloquĂ©. ContournĂ© : import des flux NVD 2.0 rĂ©els (miroir fkie-cad) â les 1 733 CVE du catalogue KEV complĂ©tĂ©es par leur CVSS NVD |
| EPSS | â toujours bloquĂ©, aucun miroir fiable trouvĂ© |
| RULE-01 (Tor) | â validĂ©e sur une liste rĂ©elle de 1 746 relais (miroir GitHub non officiel) : 2 relais sur 2 dĂ©tectĂ©s, l'IP propre ignorĂ©e |
| Copie des livrables sur le poste | à refaire : le poste était hors ligne le 03/10 (voir fin de livraison) |
2. Erreurs rencontrĂ©es pendant l'exĂ©cution rĂ©elle, corrigĂ©es¶
| Erreur | Cause | Correctif |
|---|---|---|
/ready en 500 et sentry db upgrade en échec avec le rÎle applicatif |
mot de passe encodé (%3A) dans l'URL : ConfigParser d'Alembic l'interprÚte comme une interpolation |
% doublé avant passage à Alembic (+ test de non-régression). Défaut antérieur au lot 2 : tout mot de passe de base contenant un caractÚre spécial cassait les migrations |
sentry config affichait les mots de passe des URL |
seules les clés nommées étaient masquées | masquage du mot de passe dans toute URL de connexion |
| Tentative SSRF absente de l'audit | rejet par la validation du schéma (422), avant la route | gestionnaire de validation qui audite les seules UnsafeFeedURLError, attribuées au porteur du jeton |
| Scénario non rejouable avant 15 min | l'attaquant simulé utilisait 127.0.0.1, ce qui bloquait le compte de test | adresse d'attaquant aléatoire (RFC 5737) via X-Forwarded-For |
| Construction d'image impossible en réseau filtré | # syntax=docker/dockerfile:1 télécharge un frontal depuis Docker Hub |
directive supprimée (aucune syntaxe avancée utilisée) |
| Lignes d'accÚs doublées | journal d'uvicorn + journal JSON sentry.http |
--no-access-log |
| Import NVD : 1,9 Go de mémoire | json.load d'un flux annuel décompressé (> 500 Mo) |
lecture en flux objet par objet : 221 Mo |
mypy en échec sous SQLAlchemy 2.1.1 (Python 3.14) |
inférence de type plus faible que 2.1.3 | annotations explicites ; vérifié sous 2.0.54, 2.1.1 et 2.1.3 |
3. Contenu du lot 2¶
RĂŽles PostgreSQL. Constat direct avec le rĂŽle sentry_app sur la base d'audit :
| Opération | Résultat |
|---|---|
SELECT / INSERT / UPDATE sur les données |
autorisé |
INSERT dans audit_events |
autorisé |
UPDATE audit_events, DELETE FROM incident_events, TRUNCATE incident_events |
permission denied (avant mĂȘme les dĂ©clencheurs) |
DROP TRIGGER, ALTER TABLE, DROP TABLE |
must be owner |
CREATE TABLE |
permission denied for schema public |
UPDATE alembic_version |
permission denied |
Sessions. AccĂšs 15 min ; jeton de rafraĂźchissement opaque, empreinte seule en base, rotatif ;
rejeu â lignĂ©e rĂ©voquĂ©e et auth.refresh DENIED dans l'audit ; dĂ©connexion ; sentry users
disable|enable|revoke-sessions.
Clés. kid dans chaque JWT ; SECRET_KEY_PREVIOUS en vérification seule ; valeur vide
traitée comme absente (sans cela, une clé précédente vide aurait été acceptée).
Redis. Mot de passe dans Compose ; démarrage refusé en production sans mot de passe ou avec celui de développement.
Import NVD hors ligne (sentry cves import) : utile pour un déploiement isolé et pour
valider M3 sans l'API.
4. Constat sur donnĂ©es rĂ©elles : le score sans EPSS¶
Avec le CVSS réel du NVD et sans EPSS, la répartition des 1 733 CVE KEV est :
| Priorité | CVE | Score moyen |
|---|---|---|
| P0 | 0 | â |
| P1 | 617 | 65,9 |
| P2 | 1 100 | 51,6 |
| P3 | 16 | 37,8 |
Sans EPSS, le score plafonne Ă 75 (CVSS 30 + KEV 25 + exploit 10 + ransomware 10) : aucune CVE ne peut atteindre P0, pas mĂȘme Log4Shell (75, P1). Avec l'EPSS de Log4Shell (â 0,94), elle passerait Ă â 98. ConsĂ©quence opĂ©rationnelle : une panne de l'API EPSS fait disparaĂźtre toutes les P0 sans alerte. Deux mesures Ă trancher par ADR en M8 :
- alerte d'exploitation si la derniĂšre synchronisation EPSS date de plus de 48 h ;
- plancher « KEV â au moins P1 » (16 CVE KEV sont aujourd'hui en P3).
Confiance : élevée sur les chiffres (calcul déterministe sur données NVD réelles) ; l'effet d'EPSS sur la répartition reste à mesurer sur Kali.
5. MĂ©triques¶
| Indicateur | Lot 1 | Lot 2 |
|---|---|---|
| Tests | 410 | 432 (+22) |
| Couverture | 94 % | 94 % (93 % sous 3.14) |
| Environnements CI rejoués | 3 | 3 (3.12 SA 2.1.3, 3.14 SA 2.1.1, 3.12 SA 2.0.54) |
| Scénario d'acceptation | 44/44 | 48/48, API en rÎle applicatif, rejouable |
| Tables / migrations | 15 / 7 | 16 / 8, une seule head |
| Opérations API / commandes CLI | 33 / 35 | 35 / 40 |
| Image Docker | non construite | construite et exécutée (base de substitution) |
pip-audit / bandit haut-moyen |
0 / 0 | 0 / 0 |
| RafraĂźchissement de session (latence) | â | 9,8 ms |
6. Limites assumĂ©es¶
- Un client qui rafraßchit deux fois en parallÚle est déconnecté (rejeu strict).
refresh_tokenssans purge planifiée (M11).- Base Docker de substitution : la taille d'image mesurée (730 Mo) n'est pas représentative de
python:3.12-slim(â 250 Mo attendus) ; le job GitLabimage-dockerreste la rĂ©fĂ©rence.
7. Prochaines Ă©tapes¶
- Fusion
release/v0.1.1âmain, tagv0.1.1. - MR
feature/m7-production-hardening(lots 1 et 2) âmain. - Sur Kali : crĂ©er le rĂŽle applicatif, passer
.envaux nouvelles variables,sentry db upgrade, scénario 48/48,sentry cves sync(NVD + EPSS) pour mesurer la vraie répartition. - Lot 3 de M7 : reverse proxy TLS (Caddy), scan d'image Trivy en CI, conteneur de migration.
- ADR M8 sur la dépendance à EPSS et le plancher KEV.