Moteur OpenGrep¶
Le serveur Controller lance OpenGrep comme second moteur d'analyse statique lors d'un scan de code complet
(security-review-ci scan-code). Le scanner intégré reste actif et inchangé. Les scans de fragments
(scan_code) ne lancent aucun processus externe.
Image Docker¶
L'image -opengrep (latest-opengrep,
X.Y.Z-opengrep) contient une version épinglée d'OpenGrep dans /usr/local/bin/opengrep, vérifiée par son
empreinte SHA-256 à la construction (cible opengrep du Dockerfile) et décompactée à ce moment, en
lecture seule, pour qu'un scan ne l'extraie jamais : utilisez-la pour le serveur Controller. Les
règles par défaut sont installées et tenues à jour à chaque démarrage. L'image par défaut ne contient pas OpenGrep et définit SECREVIEW_OPENGREP_ENABLED=false. Avec une installation du paquet
PyPI, installez OpenGrep vous-même et définissez SECREVIEW_OPENGREP_BINARY s'il n'est pas dans
/usr/local/bin.
Configuration¶
Le moteur est activé par défaut (sauf dans l'image Docker par défaut, sans OpenGrep), mais il ne s'exécute qu'une fois au moins une règle YAML installée : sans
règle, scan-code n'exécute que le scanner intégré. Définissez SECREVIEW_OPENGREP_ENABLED=false pour le
désactiver. Variables d'environnement du serveur Controller :
| Variable | Valeur par défaut | Description |
|---|---|---|
SECREVIEW_OPENGREP_ENABLED |
true |
Active OpenGrep pour les scans de code complet |
SECREVIEW_OPENGREP_BINARY |
/usr/local/bin/opengrep |
Chemin de l'exécutable OpenGrep |
SECREVIEW_OPENGREP_RULES_DIR |
/var/lib/secreview/rules/opengrep |
Répertoire des packs de règles YAML |
SECREVIEW_OPENGREP_TIMEOUT_SECONDS |
600 |
Durée maximale d'un scan OpenGrep |
SECREVIEW_OPENGREP_MAX_CONCURRENT_SCANS |
1 |
Scans OpenGrep simultanés dans un processus du serveur Controller ; un scan au-delà est refusé avec 503 et Retry-After |
SECREVIEW_OPENGREP_JOBS |
2 |
Cœurs utilisés par un scan OpenGrep (--jobs) |
SECREVIEW_OPENGREP_MAX_MEMORY_MB |
2048 |
Mémoire en Mio d'un scan OpenGrep (--max-memory, 0 : sans limite) |
Les règles par défaut sont installées au démarrage par l'image
-opengrep, ou par security-review-controller opengrep install ; ajoutez vos propres packs de
règles dans le répertoire configuré, par exemple en montant un répertoire administré sur
/var/lib/secreview/rules/opengrep (gardez-le sur un volume, pour que les modifications et
suppressions faites dans la page Règles OpenGrep survivent à un nouveau conteneur). Les règles
ne sont jamais téléchargées. Le répertoire doit contenir au moins un fichier .yml ou .yaml.
Lorsque le moteur est activé, le Controller écrit les sources déjà reçues du client CI dans un répertoire
temporaire privé, exécute OpenGrep sans shell, analyse sa sortie JSON puis supprime l'espace de travail.
Les résultats sont convertis au format de findings existant et intégrés au même rapport et au même export
SARIF que les résultats du scanner natif. Les identifiants des règles OpenGrep sont préfixés par
OPENGREP: (OPENGREP:secreview.python.taint-sql). OpenGrep ignore les chemins de sa liste
d'exclusion par défaut (répertoires de tests comme tests/, node_modules/...).
Règles par défaut¶
Security Review fournit 90 règles OpenGrep écrites pour le projet (licence Apache-2.0, comme le
reste du code) : les packs communautaires ne sont pas redistribués, car leurs licences
(Semgrep Rules License, ou LGPL avec la Commons Clause pour le fork opengrep-rules) interdisent
leur usage dans un produit comme celui-ci. Elles complètent les règles intégrées
avec ce qu'un motif ligne par ligne ne voit pas :
- analyse de propagation (taint) : une valeur lue dans la requête (Flask, Django, FastAPI,
Spring, servlets, Express, NestJS, ASP.NET Core,
net/http, Gin, Echo) est suivie à travers les variables et la construction de chaînes jusqu'à un appel dangereux (SQL, commande, chemin de fichier, URL sortante, redirection, template, HTML, désérialisation). Un assainissement en chemin (int(),secure_filename,path.basename,html.EscapeString...) l'arrête ; - structure : une option absente (une fabrique XML sans
disallow-doctype-decl, une archive extraite sans filtre, un serveur HTTP sans délais, un Dockerfile sansUSER) ou une combinaison d'arguments (CORS avec toute origine et identifiants).
| Langage (répertoire) | Règles | Principaux contrôles |
|---|---|---|
Python (python) |
18 | Taint : SQL, commande, eval, SSRF, chemin, redirection, template, HTML, désérialisation ; TLS, YAML, JWT, debug, CORS, archives, hachages, cookies |
Java, Spring (java) |
18 | Taint : SQL/JPQL, commande, chemin, SSRF, redirection, XSS, SpEL/OGNL, JNDI/LDAP ; désérialisation, XXE (DOM, SAX, StAX), CSRF, TLS sans vérification, nom d'hôte, chiffrements, hachages, cookies, Jackson |
JavaScript, TypeScript, Angular (javascript) |
16 | Taint : SQL, commande, eval/vm, chemin, SSRF, redirection, XSS, RegExp, XSS DOM depuis l'URL ou la route ; données message lues sans vérifier leur origine, bypassSecurityTrust*, TLS, CORS, JWT, cookies, cryptographie |
Go (go) |
11 | Taint : SQL, commande, chemin, SSRF, redirection, XSS ; InsecureSkipVerify, zip slip, délais du serveur, cryptographie, math/rand pour un secret |
C#, ASP.NET Core (csharp) |
12 | Taint : SQL (ADO.NET, EF Core, Dapper), processus, chemin, SSRF, redirection ; désérialiseurs, validation des certificats, JWT, cryptographie, DTD, encodage HTML, CORS |
Rust (rust) |
9 | Taint : SQL (sqlx, diesel, pilotes) depuis les extracteurs axum et actix-web ; SQL construit avec format!, shell, TLS, cryptographie, JWT, CORS, cookies, HTML |
Dockerfile (dockerfile) |
2 | Pas de USER avant CMD/ENTRYPOINT, dernier USER à root |
GitHub Actions (github-actions) |
4 | Injection de script avec ${{ }}, pull_request_target qui récupère le code de la pull request, action non épinglée sur un SHA, write-all |
Leurs identifiants suivent secreview.<langage>.<contrôle> (secreview.go.zip-slip) et leurs
métadonnées donnent la CWE et la catégorie OWASP, reprises dans les findings.
Tant que le moteur est activé (SECREVIEW_OPENGREP_ENABLED) et que l'exécutable OpenGrep est
présent (image -opengrep), le serveur Controller les met à jour à chaque démarrage, comme les règles TOML par défaut : une nouvelle règle
est installée, une règle restée telle qu'installée est remplacée par la nouvelle version, et une
règle modifiée ou supprimée dans la page Règles OpenGrep est laissée telle quelle. Les
empreintes des versions installées sont gardées dans .secreview-default-rules.json du
répertoire de règles ; supprimez-le pour repartir de zéro. La commande les installe à la
demande, sur le serveur Controller :
security-review-controller opengrep list # bundled rules by language
security-review-controller opengrep install # every language
security-review-controller opengrep install --language python --language javascript
security-review-controller opengrep install --overwrite # after an upgrade
install copie un fichier par règle dans SECREVIEW_OPENGREP_RULES_DIR et affiche les
identifiants installés, remplacés et ignorés (JSON). Une règle déjà présente est conservée, pour
qu'une modification faite dans la page Règles OpenGrep survive ; --overwrite la remplace
par la version du paquet (après une mise à niveau, par exemple). Pour retirer une règle,
supprimez-la dans cette page. En conteneur, lancez la commande dans le conteneur du serveur
Controller (docker compose exec controller security-review-controller opengrep install).
Sécurité opérationnelle¶
- Exécutez le Controller avec l'utilisateur non privilégié
secreviewdéjà utilisé par l'image. - Réservez la gestion des packs de règles aux administrateurs ; leur mise à jour est une opération sensible.
- Appliquez des limites CPU, mémoire et processus au conteneur. Le délai maximal, le nombre de scans simultanés, ainsi que les cœurs et la mémoire d'un scan sont appliqués par l'adaptateur (à l'expiration du délai, OpenGrep et ses processus de travail sont arrêtés), mais ne remplacent pas les limites de ressources du conteneur.
- Si OpenGrep est occupé par d'autres scans ou indisponible,
scan-codereçoit une réponse503: relancez plus tard. - Ne montez aucun secret applicatif ni chemin hôte sans rapport avec le scan dans l'espace de travail.
- Le Controller n'exécute pas les sources analysées. Il écrit toutefois les contenus reçus dans un répertoire temporaire afin qu'OpenGrep puisse les lire.
- Si des règles sont installées mais que le binaire OpenGrep est absent, ou si le scan échoue, le scan de code échoue explicitement au lieu de signaler silencieusement un succès limité au scanner natif.
Gestion des règles depuis l’interface web¶
Le Controller propose une page de gestion authentifiée à l’adresse /ui/opengrep-rules.
Les utilisateurs disposant de rules.read peuvent consulter les fichiers YAML du répertoire
SECREVIEW_OPENGREP_RULES_DIR. Ceux disposant de rules.manage peuvent créer, modifier,
valider et supprimer ces fichiers. Chaque fichier géré contient exactement une règle et son
identifiant YAML doit correspondre à celui du fichier. Toute écriture est validée avec
opengrep validate <fichier> avant un remplacement atomique. Le Controller ne télécharge
aucun pack de règles et ne suit aucune source distante à la place de l’administrateur.
Règles proposées par les agents¶
Pendant une revue, quand un problème confirmé suit un motif vulnérable que le scan n'a pas
relevé et qui peut se répéter, l'agent peut proposer une règle OpenGrep avec l'outil MCP
propose_opengrep_rule (outils) : la règle YAML, son motif et
du code de test (cas ruleid: et ok:). La règle n'est pas installée : le serveur MCP
enregistre seulement la proposition en base, et les prompts de revue demandent à l'agent de ne
proposer une règle qu'après avoir enregistré le rapport.
- Le fichier doit contenir exactement une règle dont l'
idest l'identifiant proposé ; le préfixesecreview.est réservé aux règles par défaut. Une règle qui semble contenir un secret, ou des caractères invisibles, est refusée. Le motif est masqué et borné comme celui d'une proposition de statut. - Le jeton doit atteindre le projet et y détenir
reports.write(comme poursave_security_report). Une nouvelle proposition avec l'identifiant d'une proposition en attente la remplace ; au plusSECREVIEW_OPENGREP_MAX_PENDING_PROPOSALSpropositions attendent en même temps. - Les propositions en attente sont listées en haut de la page Règles OpenGrep pour les
utilisateurs disposant de
rules.manage. Examiner en ouvre une dans l'éditeur avec son projet, son auteur, son motif et son code de test : l'approbateur peut corriger le YAML (pas son identifiant), le valider avec OpenGrep, puis l'Approuver et installer ou la Rejeter avec un motif facultatif. - Seule une personne connectée à l'interface web décide : un jeton Bearer, qu'un agent peut
détenir, reçoit
403. Une approbation valide la règle avecopengrep validateet crée son fichier ; elle ne remplace jamais une règle installée (409). La proposition, l'approbation et le rejet sont inscrits au journal d'audit.
| Route | Permission | Rôle |
|---|---|---|
GET /api/v1/opengrep/proposals?status=pending |
rules.manage |
Propositions d'un statut (pending par défaut, approved, rejected), les plus récentes d'abord |
POST /api/v1/opengrep/proposals/{id}/approve |
rules.manage, session web |
Corps {"content": null} (ou le YAML corrigé) : valide et installe la règle |
POST /api/v1/opengrep/proposals/{id}/reject |
rules.manage, session web |
Corps {"reason": null} : la règle n'est pas installée |