Analyse des dépendances¶
Fichiers pris en charge¶
requirements*.txt, pyproject.toml (PEP 621/735, Poetry), poetry.lock, Pipfile.lock,
uv.lock, package.json, package-lock.json / npm-shrinkwrap.json, yarn.lock (v1 et
berry), pom.xml, build.gradle(.kts), SBOM CycloneDX (bom.json, bom.xml, sbom.json,
*.cdx.json, *.cdx.xml...).
Dans un uv.lock, le projet lui-même et les membres de son workspace (sources editable ou
virtual) ne sont pas des dépendances et sont ignorés ; toute autre source git, url,
path, directory ou editable lève DEP-003.
SBOM CycloneDX (dépendances transitives)¶
pom.xml et build.gradle ne listent que les dépendances directes : leurs dépendances
transitives, souvent les vulnérables, ne sont pas vérifiées (une note le rappelle dans le
résultat). Générez dans le pipeline un SBOM CycloneDX de l'arbre de dépendances résolu, puis
analysez-le :
# Maven : écrit target/bom.json et target/bom.xml
mvn org.cyclonedx:cyclonedx-maven-plugin:makeAggregateBom
security-review-ci scan-deps target/bom.json --project mon-projet --require-database
Avec Gradle, la tâche cyclonedxBom du plugin org.cyclonedx.bom produit le même fichier ;
npm sbom --sbom-format cyclonedx le fait pour npm.
- Le SBOM est lu en JSON (
bomFormat: "CycloneDX") ou en XML (espace de noms CycloneDX) ; les composants imbriqués sont inclus. Un SBOM XML contenant unDOCTYPEou uneENTITYest refusé. - Chaque composant est identifié par son package URL (
purl) :pkg:maven/...(Maven),pkg:npm/...(npm) etpkg:pypi/...(PyPI). Un SBOM peut mélanger ces écosystèmes. Les autres types (pkg:golang,pkg:nuget...) et les composants sanspurlsont comptés dans une note et ne sont pas vérifiés. - Les versions sont résolues : le SBOM est traité comme un lockfile. Un composant de portée
excludedest marquédev; une version Maven-SNAPSHOTlèveDEP-002.
Base de vulnérabilités hors ligne (format OSV)¶
Le serveur MCP n'appelle aucun service externe : il consulte une base d'avis OSV stockée en base de données. Deux façons de l'alimenter :
- import manuel (aucun accès réseau requis) ;
- mise à jour quotidienne par le contrôleur, s'il a le droit de sortir sur Internet, directement ou par un proxy.
Import manuel¶
Sur une machine connectée, téléchargez les exports d'osv.dev
(https://osv-vulnerabilities.storage.googleapis.com/PyPI/all.zip, idem npm et Maven),
transférez-les, puis importez-les (opération réservée à la CLI, idempotente) :
security-review-controller advisories import PyPI.zip # .json, dossier ou .zip
security-review-controller advisories import npm.zip
security-review-controller advisories import Maven.zip --ecosystem Maven # filtre facultatif
security-review-controller advisories status
Mise à jour automatique par le contrôleur¶
Avec SECREVIEW_OSV_AUTO_UPDATE=true, security-review-controller serve télécharge les
exports all.zip de chaque écosystème et les importe, puis recommence toutes les 24 heures :
SECREVIEW_OSV_AUTO_UPDATE=true
# Facultatif : proxy HTTP sortant du contrôleur (identifiants acceptés, jamais journalisés)
HTTPS_PROXY=http://utilisateur:motdepasse@proxy.example.com:3128
- Désactivée par défaut. Le serveur MCP, lui, ne se connecte jamais à l'extérieur.
- L'échéance dépend de l'âge de la base (dernier import, manuel ou automatique) : un
redémarrage ou une seconde réplique du contrôleur ne retélécharge pas avant la fin de
l'intervalle (
SECREVIEW_OSV_UPDATE_INTERVAL_HOURS, 24 par défaut). Une base vide ou trop ancienne est mise à jour dès le démarrage. - Proxy : le téléchargement passe par le proxy sortant du contrôleur, donné par les
variables standard
HTTPS_PROXY(sinonHTTP_PROXY; noms en minuscules acceptés ;http://[utilisateur:mot de passe@]hôte:port,hôte:portvalanthttp://hôte:port, tunnelCONNECTvers le site HTTPS), sauf vers les hôtes deNO_PROXY. Le même proxy sert à la connexion OIDC. Sans ces variables, la connexion est directe. Si le proxy inspecte le TLS, donnez sa CA avecSECREVIEW_OSV_CAFILE(elle remplace alors les CA du système). - Miroir :
SECREVIEW_OSV_URLremplace la source (Nexus, Artifactory, bucket interne…) tant qu'il sert<URL>/<écosystème>/all.zipen HTTPS. HTTP en clair, identifiants dans l'URL et redirections vers autre chose que HTTPS sont refusés. SECREVIEW_OSV_ECOSYSTEMS(PyPI,npm,Mavenpar défaut) limite les exports téléchargés ; chaque archive est bornée parSECREVIEW_OSV_MAX_DOWNLOAD_MB(1024 Mio), écrite dans un dossier temporaire puis supprimée.- Un écosystème en échec (réseau, taille, archive invalide) n'empêche pas les autres ; il est journalisé et une nouvelle tentative a lieu une heure plus tard.
Hôtes sans proxy¶
NO_PROXY (ou la liste de l'écran Proxy sortant) donne, séparées par des virgules,
les destinations jointes sans le proxy :
| Entrée | Exemple | Effet |
|---|---|---|
| Domaine | corp.example ou .corp.example |
Le domaine et tous ses sous-domaines (sso.corp.example) |
| Joker de sous-domaines | *.corp.example |
Identique à .corp.example |
| Adresse IP | 10.0.0.5, [fd00::5] |
Cette adresse (un port éventuel, 10.0.0.5:8443, est ignoré) |
| Tout | * |
Aucune connexion ne passe par le proxy |
Une adresse ne s'applique qu'à une URL dont l'hôte est cette adresse IP
(https://10.0.0.5/...) : un nom d'hôte n'est jamais résolu. Pour contourner le proxy vers un
serveur interne joint par son nom, indiquez son domaine. Les plages d'adresses (CIDR,
10.0.0.0/8) ne sont pas prises en charge : dans NO_PROXY, une telle entrée ne correspond à
aucun hôte, et l'écran Proxy sortant la refuse. La boucle locale (localhost,
127.0.0.0/8, ::1) est toujours jointe directement.
NO_PROXY=.corp.example,10.0.0.5
Le proxy peut aussi être choisi par un administrateur dans l'écran
Proxy sortant de l'interface web, pour les variables
non définies : HTTPS_PROXY (sinon HTTP_PROXY) et NO_PROXY, quand elles sont définies,
sont prioritaires sur les valeurs de l'écran. Elles s'appliquent au téléchargement suivant. L'écran Base OSV affiche l'état de
la base, l'historique des mises à jour (planifiées, CLI ou web) et un bouton Mettre à jour
maintenant (lancement en arrière-plan, une mise à jour à la fois), disponible seulement quand
SECREVIEW_OSV_AUTO_UPDATE=true.
Pour déclencher une mise à jour à la demande (ou depuis un CronJob plutôt que depuis le
contrôleur), avec les mêmes paramètres :
security-review-controller advisories update # écosystèmes de SECREVIEW_OSV_ECOSYSTEMS
security-review-controller advisories update --ecosystem npm # option répétable
# code de sortie : 0 = tout importé, 2 = au moins un écosystème en échec ou paramètre invalide
Le contrôleur télécharge au plus quelques centaines de Mio par jour (l'export npm est le plus
gros) : prévoyez l'espace correspondant dans son dossier temporaire (/tmp).
Scan dans un pipeline (security-review-ci scan-deps)¶
Dans un pipeline, le client de pipeline
envoie les fichiers de dépendances au contrôleur, qui les compare à sa base d'avis et, avec
--save, enregistre un rapport dependency-scan du projet. Le pipeline n'a besoin ni de la
base ni du paquet, seulement d'un jeton ci
(ou admin) du projet :
export SECREVIEW_CONTROLLER_URL=https://secreview.example.com
export SECREVIEW_TOKEN=... # jeton ci limité à mon-projet
security-review-ci scan-deps package-lock.json requirements.txt \
--fail-on high --require-database --project mon-projet --save
# code de sortie : 0 = ok, 1 = bloqué, 2 = erreur
--require-databaserefuse le scan (code2, rien n'est enregistré) quand la vérification des vulnérabilités ne peut pas avoir lieu pour un fichier.- Avec
--save,--authorenregistre le nom d'utilisateur du développeur avec le rapport (voir auteur d'un rapport),--repository,--branchet--commitle contexte ; le libellé du jeton est enregistré comme appareil. - Chaque fichier est limité au
SECREVIEW_MAX_DEPENDENCY_CHARSdu contrôleur, la requête àSECREVIEW_MAX_SCAN_REQUEST_MB. Les liens symboliques ne sont pas lus.
Scan avec un serveur partagé (hook de commit)¶
security-review-mcp scan-deps envoie les fichiers de dépendances à l'outil scan_dependencies
d'un serveur MCP partagé : le scan utilise la base d'avis de ce serveur, sans import local. Il
faut un jeton de rôle mcp ou admin, par exemple un jeton MCP personnel (voir
enrôlement).
export SECREVIEW_MCP_URL=https://secreview.example.com
export SECREVIEW_TOKEN=<token>
security-review-mcp scan-deps uv.lock web/package-lock.json --require-database
# code de sortie : 0 = ok, 1 = bloqué, 2 = erreur (serveur injoignable, jeton refusé...)
Un jeton absent ou refusé (inconnu, révoqué ou expiré) se termine par une erreur qui invite à se connecter à l'interface web pour créer un nouveau jeton MCP personnel (voir jeton refusé).
- Mêmes options et même sortie que
security-review-ci scan-deps(--fail-on,--format,--require-database) ; rien n'est enregistré (pas de--save). --urlremplaceSECREVIEW_MCP_URL,--token-stdinlit le jeton sur stdin au lieu deSECREVIEW_TOKEN. Les deux variables peuvent aussi être définies dans le fichier.envdu dossier (ne le commitez jamais).- HTTP en clair est refusé hors localhost (sauf
--allow-http), comme les identifiants dans l'URL et les redirections vers une autre origine ;--cafileindique une CA interne. Les liens symboliques ne sont pas lus, car le contenu quitte la machine. - Chaque fichier est limité par le
SECREVIEW_MAX_DEPENDENCY_CHARSdu serveur.
Hook de commit (pre-commit ou prek), lancé quand un manifeste ou un lockfile change :
repos:
- repo: local
hooks:
- id: scan-deps
name: dependency scan
entry: security-review-mcp scan-deps --skip-unconfigured --require-database
language: system
files: (^|/)(uv\.lock|requirements[^/]*\.txt|pyproject\.toml|package(-lock)?\.json)$
--skip-unconfigured laisse passer le commit, avec un avertissement, quand aucune URL de serveur
n'est configurée (contributeurs sans serveur partagé).
Lire le résultat¶
Le champ vulnerability_check dit si la vérification a eu lieu :
| Valeur | Signification |
|---|---|
performed |
Les versions ont été comparées à la base |
skipped_no_advisory_database |
Aucune base importée |
skipped_no_advisories_for_ecosystem |
Aucun avis pour cet écosystème |
Liste vide ≠ dépendances sûres
Dans les deux derniers cas, une liste vide ne signifie pas que les dépendances sont
sûres. --require-database fait échouer le pipeline dans ce cas.
- Une base de plus de 30 jours est signalée.
- Une sévérité absente de l'avis est traitée comme
medium(severity_known: false). - Les versions en intervalle (
>=2) ne sont pas vérifiables : analysez le lockfile. - Pour un SBOM qui mélange des écosystèmes, la vérification est
performeddès que l'un d'eux a des avis ; une note nomme les écosystèmes qui n'ont pas pu être vérifiés. - Chaque composant est marqué
devou non. Danspyproject.toml, les extras nommées d'après le développement (dev,test,docs,lint...) et les[dependency-groups]sontdev; les autres extras (postgres...) sont installées en production et restent des dépendances d'exécution. - Règles d'hygiène
DEP-001àDEP-009: versions non épinglées, URL / VCS, HTTP, index supplémentaire,--trusted-host, etc.