# #224 — Sécurité des dépendances : pip-audit vierge (brotli, filelock, opentelemetry-api, pypdf) > Ouvert le 2026-10-25. Déclencheur : le job `security` du run CI 2303 > (commit `f29a228`, version 2.78.0) échoue sur `pip-audit` (bloquant, > #87) — **17 vulnérabilités connues dans 4 paquets**. Le job `lint` > du même run est vert ; `security` est le seul job terminé en échec > au moment du constat (`test` en file, `build`/`e2e` en attente). ## Constat (journal du job `security`, run 2303) | Paquet | Version auditée | Vulnérabilités | Corrigée en | |---|---|---|---| | brotli | 1.2.0 | PYSEC-2026-4322, GHSA-9v8h-qqgm-4m35 | 1.2.1 | | filelock | 3.32.3 | CVE-2026-112940, CVE-2026-112913, CVE-2026-112907 | 4.2.1 | | opentelemetry-api | 1.37.0 | CVE-2026-114603 | 1.45.1 | | pypdf | 6.19.0 | CVE-2026-113792, CVE-2026-113795, CVE-2026-113793, CVE-2026-113794, CVE-2026-113786, CVE-2026-113791, CVE-2026-113790, CVE-2026-113789, CVE-2026-115572, CVE-2026-115585, CVE-2026-115580 | 6.20.0 → 6.21.2 selon l'advisory (max 6.21.2) | Total : 2 + 3 + 1 + 11 = **17 vulnérabilités**. Audit local de confirmation, en deux temps : (1) un venv épinglé sur les versions du runner (brotli 1.2.0, filelock 3.32.3, opentelemetry-api 1.37.0, pypdf 6.19.0) reproduit **exactement** les 17 vulnérabilités et les versions corrigées du tableau ci-dessus ; (2) dans le venv du dépôt, `pip-audit` (avec les deux ignores déjà en place dans la CI) ne ressortait avant correctif que brotli 1.2.0 (2 advisories, fix 1.2.1) et pypdf 6.21.1 (3 advisories restants, fix 6.21.2) — ce venv a déjà filelock 4.2.4 (corrigée) et ne contient pas opentelemetry-api. L'écart avec la CI vient de l'environnement audité, pas des dépendances déclarées (voir cause). ## Cause racine Même piège que BUG-093 / BUG-095, déjà documenté dans `backend/requirements.txt` et `.gitea/workflows/ci.yml` : `pip-audit` audite **tout l'environnement Python du runner**, dont les paquets préinstallés dans la toolcache de l'image `catthehacker/ubuntu:act-latest`. `pip install -r backend/requirements.txt` répond « already satisfied » pour toute exigence transitive déjà satisfaite par la toolcache et n'aligne jamais la version vulnérable : - **pypdf 6.19.0** : préinstallée ; le plancher `>=6.16.1` (BUG-093) est satisfait, pip ne monte pas vers 6.21.2. - **brotli 1.2.0** : transitive de `fonttools[woff]` (via weasyprint), exigée en `>=1.0.1` seulement. - **filelock 3.32.3** : transitive de CacheControl (outil `pip-audit` lui-même) et préinstallée ; exigée en `>=3.8.0` seulement. - **opentelemetry-api 1.37.0** : préinstallée dans la toolcache, aucune dépendance d'ObsiGate ne la demande. ## Correctif Planchers de sécurité explicites dans `backend/requirements.txt`, selon le patron déjà en place (pyjwt, urllib3, multidict, certifi) — aucune autre dépendance touchée, aucun code applicatif modifié : - `pypdf>=6.16.1` → **`pypdf>=6.21.2`** (plancher existant relevé) ; - **`brotli>=1.2.1`** (nouveau plancher) ; - **`filelock>=4.2.1`** (nouveau plancher) ; - **`opentelemetry-api>=1.45.1`** (nouveau plancher). Garde-fou : `tests/test_ci_workflow.py::TestDependencySecurityFloors` couvre désormais aussi brotli, filelock et opentelemetry-api, et le plancher verrouillé de pypdf passe à (6, 21, 2). Le commentaire de l'étape Pip-audit de `.gitea/workflows/ci.yml` est mis à jour en conséquence (aucune commande CI modifiée). ## Exceptions (ignores) **Aucun nouvel ignore.** Les deux exceptions déjà en place dans la CI restent inchangées et ne concernent pas ces paquets : `PYSEC-2026-1325` (ecdsa, aucun correctif upstream, chemins ECDSA jamais exécutés — HS256 uniquement) et `CVE-2026-85394` (python-jose, aucun correctif upstream, non atteignable — voir le commentaire de l'étape dans `ci.yml`). ## Vérification - `pip-audit` local (mêmes ignores que la CI) après alignement de l'environnement sur les nouveaux planchers : **0 vulnérabilité non ignorée**. - Portes locales du workflow : `pytest tests/`, `ruff check backend/`, `mypy backend/ --ignore-missing-imports`, tests frontend (`validate-imports` + `unit`) — voir le commit #224. - CI Gitea complète verte exigée (lint, test, security, build, e2e) avant de considérer #224 livré. ## Livraison - Commit conventionnel `fix: … #224` ; le hook de version porte 2.78.0 → **2.78.1** (correctif) et crée le tag `v2.78.1`, publié au push ; release Gitea créée sur ce tag après vérification de sa cible. - **Redéploiement Docker requis** pour que l'image embarque les dépendances alignées (l'hôte actuel est l'environnement dev).