Semgrep (Semantic Grep) est un outil d’analyse statique multi-langage qui identifie du code par sa structure – et non simplement par son texte – en utilisant un Abstract Syntax Tree unifie et un langage de patterns riche. Ce document couvre l’architecture interne complete, du point d’entree CLI a la detection de taint sink.
Table des matieres
- Introduction
- Architecture de haut niveau
- Decomposition des composants
- Le pipeline d’analyse complet
- Decouverte et filtrage des cibles
- Parsing et optimisation des regles
- Parsing et l’AST universel
- Le moteur de matching
- Le langage intermediaire (IL) et le CFG
- Analyse de taint (Dataflow)
- Pipeline de sortie et de reporting
- Architecture OSemgrep / RPC
- Structures de donnees cles
-1. Pourquoi ?
Je travaille en tant qu’ingenieur DevSecOps depuis bientot quatre ans. Quand j’ai commence, j’avais peu d’exposition a des outils comme le SAST, le SCA ou le DAST. Mon etat d’esprit etait fermement ancre dans la securite offensive. Le test d’intrusion etait l’objectif, le reve.
Puis j’ai decouvert le SAST. Ma premiere reaction a ete un enthousiasme sincere : “C’est incroyable, de l’analyse de code automatisee a grande echelle !” Mais avec le temps, la realite s’est imposee. En pratique, la plupart des resultats tendent a etre bruyants. Les faux positifs sont abondants, et les vulnerabilites veritablement critiques sont rarement mises en lumiere par des regles pretes a l’emploi. Soyons clairs : je ne dis pas que ces outils sont inutiles, loin de la. Ils constituent une couche de defense essentielle dans tout programme de securite mature. Mais ils ont leurs limites.
Cette tension, entre la promesse et la realite du SAST, a plante une question dans ma tete qui ne voulait pas disparaitre : pourquoi ne pas construire le mien ? L’idee n’a cesse de me titiller jusqu’a ce que je decide finalement de creuser le sujet. Et quel terrier de lapin cela s’est avere etre.
Le point de depart naturel etait Semgrep. Comprendre comment il fonctionne sous le capot – le pipeline de parsing, l’AST universel, le moteur de matching, l’analyse de taint – a ete l’une des explorations intellectuelles les plus enrichissantes que j’ai faites depuis longtemps. Cet article est le resultat de cette exploration.
Il y aura d’autres articles sur ce sujet. J’ai beaucoup a dire sur l’analyse statique, et je ne fais que commencer.
No em dashes used anywhere. You may need to reload the file in your editor to see the changes.
0. Introduction
0.1 Qu’est-ce que le SAST ?
Le Static Application Security Testing (SAST) est une technique de securite en boite blanche qui analyse le code source, le bytecode ou le code binaire sans executer le programme. Un outil SAST lit le code de la meme maniere qu’un compilateur ou un interpreteur, construit un modele interne de la structure du programme et du flux de donnees, puis applique une bibliotheque de regles de securite a ce modele pour identifier les vulnerabilites.
Le SAST se positionne au stade le plus precoce possible du cycle de vie du developpement logiciel (SDLC). Ce principe de “shift-left” signifie que les bugs sont detectes avant qu’ils ne puissent atteindre un environnement de staging ou de production – reduisant considerablement le cout et l’effort de correction.
Proprietes fondamentales d’un outil SAST :
| Propriete | Description |
|---|---|
| Aucune execution requise | Analyse les fichiers source directement ; ne necessite ni serveur, ni base de donnees, ni reseau en cours d’execution |
| Conscient du langage | Comprend la syntaxe et la semantique : sait que x = y est une affectation, pas deux identifiants |
| Detection precoce des bugs | S’execute dans les pipelines CI/CD ou meme en hooks pre-commit, offrant un retour instantane aux developpeurs |
| Scalable | Peut analyser des millions de lignes de code en quelques secondes grace a l’analyse parallele |
| Deterministe | Le meme code produit toujours le meme resultat (pas d’instabilite liee au reseau ou au timing) |
SAST vs. autres approches de tests de securite
Les quatre grandes categories de tests de securite different selon deux axes : si l’acces au code source est necessaire, et si l’application doit etre en cours d’execution.
| Approche | Acces au code | Application en execution | Point d’integration typique |
|---|---|---|---|
| SAST | Oui | Non | Commit / PR / build CI |
| DAST | Non | Oui | Environnement de staging |
| IAST | Oui | Oui | Environnement QA avec agent |
| SCA | Oui (manifestes) | Non | Installation des dependances / build |
| Revue de code manuelle | Oui | Non | Sprint securite / audit |
Les programmes de securite modernes utilisent toutes ces couches ensemble. Le SAST est la premiere ligne de defense car il est le moins couteux et le plus rapide a executer.
Comment fonctionne le SAST : la technique fondamentale
La plupart des outils SAST suivent le meme pipeline fondamental :
graph LR
A[Source Code] --> B[Lexing / Tokenization]
B --> C[Parsing]
C --> D[AST]
D --> E[Security Rules Application]
E --> F[Findings]
Semgrep est unique parmi les outils SAST car il expose ce pipeline directement aux utilisateurs. Au lieu de fournir uniquement une bibliotheque de regles figee, Semgrep permet aux ingenieurs en securite d’ecrire des regles personnalisees en YAML en utilisant un langage de patterns qui reflete la syntaxe reelle du code – aucune connaissance en theorie formelle des langages n’est requise.
0.2 Histoire de Semgrep
Semgrep n’a pas ete construit de zero. Ses racines remontent a des recherches menees au sein de Facebook il y a plus de quinze ans.
La lignee pfff (2009)
En 2009, Yoann Padioleau – alors ingenieur chez Facebook – a cree pfff (“Parsing Framework for Fun”). pfff etait une bibliotheque et un ensemble d’outils OCaml capable de parser plusieurs langages de programmation (PHP, C, OCaml, Java) en une representation AST commune. L’objectif etait de construire des outils de navigation de code, de refactoring et d’analyse statique legere qui fonctionnaient de maniere uniforme sur le codebase polyglotte de Facebook.
pfff a introduit deux idees fondatrices sur lesquelles Semgrep s’appuie encore aujourd’hui :
- Un AST universel (
AST_generic) partage entre tous les langages supportes. - sgrep – un prototype de “semantic grep” qui permettait aux ingenieurs d’ecrire des patterns de code structurels (avec des wildcards) qui matchaient l’AST de pfff au lieu du texte brut.
De sgrep a Semgrep (2013-2019)
Le prototype sgrep a demontre que le matching structurel etait pratique et utile pour trouver des bugs a grande echelle au sein de Facebook. Le concept a ete affine en interne pendant plusieurs annees mais n’a pas encore ete rendu public. Le coeur OCaml a continue a evoluer aux cotes de pfff.
Lancement open source (2020)
En 2020, r2c (Return to Corporation, renomme plus tard Semgrep Inc.) a externalise la technologie et a publie Semgrep en tant qu’outil libre et open source sous licence LGPL-2.1. La publication incluait :
- Un CLI Python encapsulant le binaire OCaml.
- Le Semgrep Registry – une bibliotheque de regles de securite maintenue par la communaute.
- Le support de plus de 10 langages des le premier jour.
Cette publication a ete une percee : pour la premiere fois, n’importe quel developpeur ou ingenieur en securite pouvait ecrire des patterns de code structurels sans avoir besoin d’un doctorat en analyse de programmes.
Expansion et commercialisation (2021-2022)
Semgrep Inc. a commence a developper des capacites commerciales au-dessus du coeur OSS :
- Semgrep Pro / DeepSemgrep (2021) : Ajout de l’analyse de taint inter-procedurale et du dataflow cross-file – permettant de suivre comment les donnees tainted se propagent non seulement au sein d’une fonction mais a travers les frontieres de modules et de codebases entiers.
- Semgrep Supply Chain / SCA (2022) : Integration de l’analyse des manifestes de dependances pour detecter les CVE connues dans les bibliotheques tierces, reliant l’analyse de reachability (“cette fonction vulnerable est-elle reellement appelee ?”) au moteur SAST.
- Semgrep Secrets (2022-2023) : Extension du langage de regles pour detecter les identifiants codes en dur et les cles API, avec un scoring d’entropie et une validation en ligne assistee par IA.
OSemgrep et le Semgrep moderne (2023-present)
Alors que le CLI Python devenait un goulot d’etranglement en termes de performance et de maintenance, Semgrep Inc. a lance le projet OSemgrep : une reimplementation complete du CLI Python en OCaml, fusionnant le CLI et le moteur coeur en un seul binaire. Cela elimine le surcout des sous-processus, permet une integration plus etroite avec l’IDE via les protocoles RPC et LSP, et simplifie le deploiement.
| Ere | Evenements cles |
|---|---|
| 2009 | pfff cree chez Facebook ; framework AST multi-langage |
| 2013 | Prototype sgrep : matching de patterns structurels sur l’AST |
| 2020 | Semgrep OSS publie par r2c ; lancement du Registry |
| 2021 | DeepSemgrep : taint inter-procedurale + analyse cross-file |
| 2022 | Supply Chain (SCA) et detection de Secrets ajoutees |
| 2023 | Debut de la reecriture OSemgrep ; integrations RPC/LSP IDE |
| 2024 | Semgrep Secrets GA ; support des outils MCP ; 30+ langages |
1. Architecture de haut niveau
Semgrep est divise en deux niveaux : un CLI Python qui gere les aspects orientes utilisateur, et un moteur coeur OCaml qui effectue tout le travail lourd – parsing, matching et analyse de dataflow.
graph TD
subgraph Python CLI
A1[Config / Rules Resolution]
A2[Target Discovery]
A3[Output Formatting]
end
subgraph OCaml Core Engine
B1[Parsing]
B2[Pattern Matching]
B3[Dataflow / Taint Analysis]
end
A1 --> B1
A2 --> B1
B1 --> B2
B2 --> B3
B3 --> A3
2. Decomposition des composants
2.1 Semgrep CLI (cli/src/semgrep/)
| Module | Responsabilite |
|---|---|
main.py / cli.py | Point d’entree, routage des sous-commandes (scan, ci, test, login) |
config_resolver.py | Recupere les regles depuis des chemins locaux, des URLs ou le Semgrep Registry |
target_manager.py | Parcourt le systeme de fichiers, applique les regles .semgrepignore / .gitignore |
core_runner.py | Serialise le plan de scan et invoque semgrep-core ; collecte la sortie JSON |
run_scan.py | Orchestre le flux de scan complet (regles -> cibles -> core -> sortie) |
output.py / scan_report.py | Post-traitement des resultats, deduplication, suppression # nosemgrep |
join_rule.py | Evalue les regles de jointure multi-fichiers en combinant les liaisons de metavariables |
engine.py | Detecte quelle variante de moteur utiliser (OSS / Pro / DeepSemgrep) |
metrics.py / telemetry.py | Collecte et envoie des metriques d’utilisation anonymes |
rpc.py / rpc_call.py | Pont JSON-RPC optionnel pour les integrations IDE/LSP |
2.2 Semgrep Core (src/)
| Repertoire | Fichiers cles | Responsabilite |
|---|---|---|
src/main | Main.ml | Point d’entree du binaire ; parse les arguments CLI et dispatche |
src/core_scan | Core_scan.ml, Parmap_targets.ml | Orchestration parallele du scan sur la matrice cible/regle |
src/targeting | Find_targets.ml, Semgrepignore.ml, Guess_lang.ml | Decouverte de fichiers, detection du langage, regles d’exclusion |
src/rule | Rule.ml, Parse_rule.ml, Xpattern.ml | Modele de donnees des regles et parsing YAML |
src/parsing | Parse_target.ml, Pfff_or_tree_sitter.ml, Parse_pattern.ml | Parsing source et pattern -> AST_generic |
src/ast_generic | AST_generic.ml (dans libs/) | Definitions de types de l’AST universel |
src/naming | Naming_AST.ml | Resolution des noms/scopes sur l’AST parse |
src/prefiltering | Analyze_rule.ml, File.ml | Pre-scan rapide pour ignorer les fichiers non pertinents |
src/matching | Pattern_vs_code.ml, Matching_generic.ml | Matching structurel de patterns au coeur du moteur |
src/engine | Match_rules.ml, Match_search_mode.ml, Match_taint_spec.ml | Dispatch des regles, mode recherche, specification taint |
src/il | IL.ml, CFG.ml, Fun_CFG.ml | Langage Intermediaire + Graphe de Flux de Controle |
src/analyzing | AST_to_IL.ml, CFG_build.ml, Dataflow_core.ml, Constant_propagation.ml | Abaissement AST->IL, construction du CFG, dataflow generique |
src/tainting | OSS_dataflow_tainting.ml, Taint.ml, Taint_shape.ml, Taint_lval_env.ml | Propagation de taint et detection de sink |
src/fixing | Autofix application | Application des corrections de code suggerees par les regles |
src/sca | Dependency analysis | Software Composition Analysis (SCA) |
3. Le pipeline d’analyse complet
graph LR
S1[CLI Entry] --> S2[Target Discovery]
S2 --> S3[Rule Parsing]
S3 --> S4[Parsing / AST]
S4 --> S5[Matching]
S5 --> S6[Taint / Dataflow]
S6 --> S7[Output]
4. Decouverte et filtrage des cibles
4.1 Flux de decouverte des fichiers
graph LR
A[File Discovery] --> B[Language Detection]
B --> B1[--lang flag]
B --> B2[File extension]
B --> B3[Shebang line]
B --> C[.semgrepignore Filtering]
C --> D[Target List]
4.2 Detection du langage (Guess_lang.ml)
La detection est multi-couche (par ordre de priorite) :
- Flag explicite
--lang– prend le dessus sur toutes les heuristiques - Extension de fichier –
.py-> Python,.ts-> TypeScript, etc. - Ligne shebang (
#!/usr/bin/env python3) .semgrepignore/ selecteurspaths:des regles
4.3 Le systeme .semgrepignore (Semgrepignore.ml)
La superposition
.semgrepignore: valeurs par defaut integrees <.semgrepignoredu depot <.gitignore< flags CLI--exclude/--include. Les regles les plus tardives l’emportent ; le prefixe!inverse.
5. Parsing et optimisation des regles
5.1 Structure YAML des regles
Une regle Semgrep contient :
id- identifiant uniquelanguages- langage(s) cible(s)pattern/patterns/pattern-either- la formulepattern-not/pattern-not-inside- clauses negativesmetavariable-*- contraintes sur les metavariables (regex, type, comparaison, pattern)mode-search(par defaut) outaintfix- modele d’autofix optionnel
5.2 Pipeline de parsing des regles
graph LR
A[YAML Input] --> B[Parse YAML]
B --> C[Extract Patterns]
C --> D[Parse Pattern Strings]
D --> E[Compile to Pattern AST]
5.3 Algebre de formules
Les regles peuvent exprimer une logique booleenne sur les patterns :
| Operateur | Signification |
|---|---|
pattern | Matche ce pattern exact |
patterns (AND) | Tous les sous-patterns doivent matcher |
pattern-either (OR) | N’importe quel sous-pattern peut matcher |
pattern-not | Exclure si ce pattern matche |
pattern-inside | Le match doit etre a l’interieur de ce pattern |
pattern-not-inside | Le match ne doit pas etre a l’interieur de ce pattern |
focus-metavariable | Rapporte la position d’une metavariable specifique |
metavariable-regex | La valeur de la metavariable doit correspondre a une regex |
metavariable-pattern | La valeur de la metavariable doit elle-meme matcher un sous-pattern |
metavariable-type | Le type de la metavariable doit correspondre (langages types) |
metavariable-comparison | Comparaison numerique/chaine sur la metavariable |
5.4 Prefiltrage (src/prefiltering/)
Avant tout parsing, les regles sont analysees statiquement pour extraire les chaines de caracteres litterales obligatoires. Un scan de type filtre de Bloom sur les octets bruts du fichier permet au moteur d’ignorer les fichiers qui ne peuvent manifestement correspondre a aucune regle active – eliminant souvent plus de 90 % des fichiers sans solliciter le parser.
Prefiltrage : Les regles sont analysees statiquement pour extraire les chaines litterales obligatoires. Les fichiers ne contenant aucune de ces chaines sont ignores avant le parsing – eliminant souvent plus de 90 % du corpus.
6. Parsing et l’AST universel
6.1 Pourquoi un AST universel ?
Semgrep supporte plus de 30 langages en utilisant un moteur de matching unique en normalisant l’AST de chaque langage en AST_generic – une lingua franca pour la structure du code. Ajouter un nouveau langage revient a ecrire uniquement un parser qui produit ce type ; la logique de matching est reutilisee automatiquement.
6.2 Backends de parsing
graph LR
subgraph Languages
L1[Python]
L2[Java]
L3[Go]
L4[JS / TS]
L5[...]
end
subgraph Backends
B1[tree-sitter]
B2[pfff]
end
L1 --> B2
L2 --> B1
L3 --> B1
L4 --> B1
L5 --> B1
B1 --> U[AST_generic]
B2 --> U
6.3 Normalisation de l’AST et nommage
Apres le parsing brut, deux passes enrichissent l’AST generique :
- Normalisation (
Normalize_generic.ml) : Canonicalise le sucre syntaxique (par ex.,x += 1->x = x + 1). - Resolution des noms (
Naming_AST.ml) : Resout les references de variables vers leur scope de definition. Cela permet au moteur de distingueros.path.join(la fonction de la bibliotheque standard) d’unpath.joinlocal.
graph LR
A[Raw AST] --> B[Normalisation]
B -->|Canonicalise sugar| C[Name Resolution]
C -->|Scope binding| D[Enriched AST]
6.4 Parsing des patterns
Les patterns de regles passent par les memes parsers mais avec un point d’entree dedie (Parse_pattern.ml). Les tokens de metavariables ($X, $...ARGS) sont injectes comme des noeuds AST speciaux avant le parsing afin que la grammaire les traite comme des expressions valides – puis le moteur les interprete pendant le matching.
7. Le moteur de matching
7.1 Architecture globale du matching
graph TD
A[Match_rules] --> B[Search Engine]
A --> C[Taint Engine]
B --> D[Range_with_metavars]
C --> D
7.2 Pattern_vs_code.ml – le matcher central
C’est le plus gros fichier du codebase (~155 Ko). Il implemente un comparateur structurel a descente recursive entre un noeud AST de pattern et un noeud AST de code en utilisant le pattern Monadic_bind d’OCaml.
graph LR
A[Pattern AST] --> C[Recursive Structural Comparison]
B[Code AST] --> C
C --> D[Metavar Binding]
D --> E{Match?}
E -->|Yes| F[Match]
E -->|No| G[No Match]
Regles de matching cles :
| Construction de pattern | Comportement de matching |
|---|---|
$X (metavariable majuscule) | Se lie a toute expression/identifiant unique ; les utilisations suivantes imposent l’egalite |
$...ARGS (metavariable ellipsis) | Se lie a toute sequence d’arguments |
... (ellipsis) | Matche toute sequence d’instructions/arguments/champs |
Litteral "foo" | Matche la chaine litterale exacte |
_ | Matche tout noeud unique sans liaison |
<... X ...> (expression profonde) | Recherche X a l’interieur de toute sous-expression |
7.3 Contraintes sur les metavariables (filtres post-match)
Apres un match structurel brut, le moteur evalue les clauses de contraintes sur les metavariables en sequence. Toutes doivent etre satisfaites pour que le resultat soit rapporte.
graph LR
A[Raw Match] --> B[Type Check]
B --> C[Regex Check]
C --> D[Comparison Check]
D --> E[Metavar-analysis]
E --> F[Final Finding]
7.4 Visiteur de matching (Matching_visitor.ml)
Le visiteur pilote la tentative de match sur chaque noeud de l’AST du code. Pour chaque formule de regle, il :
- Parcourt l’AST du code de haut en bas.
- Tente le pattern a chaque noeud.
- Collecte les
Range_with_metavars– la plage de code qui a matche accompagnee des liaisons de metavariables. - Applique les operateurs de formule booleenne (
AND,OR,NOT,INSIDE) pour combiner les matchs bruts.
8. Le langage intermediaire (IL) et le CFG
Le matching en mode recherche fonctionne directement sur l’AST. Le mode taint necessite de comprendre l’ordre d’execution, le moteur abaisse donc d’abord l’AST en un langage intermediaire (IL) puis construit un graphe de flux de controle (CFG).
8.1 AST -> IL (AST_to_IL.ml)
graph LR
A["AST (tree)"] --> B[AST_to_IL.ml]
B --> C["Linear IL Instructions (3-address form)"]
L’IL simplifie le dataflow en rendant tous les effets de bord explicites sous forme d’instructions discretes, chacune avec un cote gauche (cible d’affectation) et un cote droit (expression) clairement definis, eliminant les expressions imbriquees complexes.
8.2 Construction du CFG (CFG_build.ml)
graph LR
A[Linear IL] --> B[CFG_build.ml]
B --> C["Control Flow Graph (basic blocks + edges)"]
8.3 Propagation de constantes (Constant_propagation.ml)
Avant l’analyse de taint, le moteur execute une propagation de constantes sparse sur le CFG. Cela resout :
- Les chaines litterales assignees a des variables (
url = "http://evil.com") - L’arithmetique simple sur les constantes entieres
- La concatenation de constantes de chaines connues
Cela enrichit l’IL afin que les patterns de taint puissent matcher la valeur effective des expressions, et non simplement leur forme syntaxique.
9. Analyse de taint (Dataflow)
9.1 Flux de taint de bout en bout
graph LR
A[Taint Rule Spec] --> B[Instantiate Sources / Sinks / Sanitizers]
B --> C[Analyze CFG with Fixpoint]
C --> D[Emit Taint Findings]
9.2 Moteur de point fixe (Dataflow_core.ml)
L’algorithme de dataflow central est une analyse forward basee sur une worklist :
graph TD
A[Initialize Worklist] --> B[Pop Node]
B --> C[Transfer Function]
C --> D[Update State]
D --> E{Changed?}
E -->|Yes| F[Add Successors to Worklist]
F --> G{Worklist Empty?}
E -->|No| G
G -->|No| B
G -->|Yes| H[Done]
9.3 Representation du taint (Taint.ml / Taint_shape.ml)
Le taint n’est pas un simple booleen – il porte des informations de provenance :
| Concept | Representation |
|---|---|
| Taint label | Quelle regle source a produit ce taint (permet le matching par label) |
| Taint call stack | La chaine d’appels de fonctions par laquelle le taint s’est propage |
| Taint shape | Taint par champ/index (Taint_shape.ml) : obj.field peut etre tainted independamment de obj |
| Xtaint | Clean / Tainted(set) / Both – indique quand une valeur est a la fois clean et tainted (par ex., via des branches) |
9.4 Regles de propagation du taint
Regles de propagation du taint :
x = tainted_ytaintex;x.f = tainted_ytainte le champx.f; la valeur de retour d’un appel est tainted si une regle de propagation s’applique ; l’interpolation de chaines avec des donnees tainted tainte le resultat ; les appels de sanitizer suppriment le taint.
9.5 Matching source / sink / sanitizer (Taint_spec_match.ml)
La strategie du “meilleur match” empeche le double rapportage :
Strategie du meilleur match (
Taint_spec_match.ml) : Lorsque plusieurs noeuds AST chevauchants matchent un pattern source/sink (par ex.,foovsfoo.bar), le moteur ne conserve que le match le plus long/le plus specifique pour eviter le double rapportage.
9.6 Analyse intra- vs inter-procedurale
| Mode | Portee | Cross-function | Notes |
|---|---|---|---|
| Intra-procedurale (OSS) | Fonction unique | Non | Les parametres de fonction sont consideres comme potentiellement tainted |
| Inter-procedurale (Pro) | Programme entier / cross-file | Oui | Construit le graphe d’appels ; calcule des resumes de taint par fonction ; propage a travers les sites d’appel |
10. Pipeline de sortie et de reporting
10.1 Sortie Core -> Formatage CLI
graph LR
A[Core JSON] --> B[Deduplication]
B --> C[Nosemgrep Filtering]
C --> D["Format (text / json / sarif / ...)"]
D --> E[Output]
10.2 Codes de sortie
| Code | Signification |
|---|---|
0 | Aucun resultat (ou --error non defini) |
1 | Resultats presents (quand le flag --error est utilise) |
2 | Erreur de scan (erreur de parsing, erreur de regle) |
3 | Arguments invalides |
123 | Impossible de se connecter au Semgrep Registry |
10.3 Le systeme de suppression # nosemgrep
Suppression
# nosemgrep: Si un resultat se trouve a la ligne N et que la ligne N ou N-1 contient# nosemgrep(optionnellement suivi d’une liste d’identifiants de regles separes par des deux-points), le resultat est supprime et non rapporte.
11. Architecture OSemgrep / RPC
11.1 OSemgrep (src/osemgrep/)
OSemgrep est la reimplementation en OCaml du CLI Python – un effort a long terme pour integrer l’ensemble du CLI dans le binaire OCaml, eliminant la dependance Python pour les scenarios critiques en performance ou embarques.
OSemgrep vs pysemgrep : Le CLI Python invoque
semgrep-corecomme sous-processus et echange du JSON via stdin/stdout. OSemgrep (la reimplementation en OCaml) appelle le core directement comme bibliotheque, eliminant la frontiere du sous-processus et la dependance au runtime Python.
11.2 Pont RPC / LSP (src/rpc/, cli/src/semgrep/rpc.py)
Pour les integrations IDE, Semgrep expose une interface JSON-RPC :
Pont RPC / LSP : L’IDE envoie des evenements LSP au serveur de langage (
rpc.py/lsp_legacy/). Le serveur les transmet comme requetes de scan JSON-RPC au Core. Les resultats sont retournes sous forme de diagnostics LSP et affiches comme annotations en ligne dans l’editeur.
12. Structures de donnees cles
12.1 Hierarchie des noeuds AST_generic (simplifiee)
L’union any couvre tous les types de noeuds. Les sous-types les plus courants :
| Type | Variantes |
|---|---|
| Expr | Literal, Id, Call, Assign, BinOp, Lambda, Conditional, … |
| Stmt | ExprStmt, If, For, Return, Try, Block, … |
| Type | TyName, TyFun, TyArray, TyGeneric, … |
| Definition | FuncDef, ClassDef, VarDef, … |
| Directive | ImportFrom, ImportAll, Pragma, … |
12.2 Rule.t (enregistrement OCaml, simplifie)
| Champ | Type | Description |
|---|---|---|
id | Rule_ID.t | Identifiant unique de la regle |
languages | Language.t list | Langages cibles |
formula | Formula | Formule de pattern (mode recherche) |
taint_spec | Taint_spec | Specification source/sink/sanitizer (mode taint) |
severity | Error | Warning | Info | Inventory | Severite du resultat |
fix | string option | Modele d’autofix |
metadata | JSON blob | Tags OWASP, CWE, confiance |
paths | selectors | Filtres de chemins include/exclude |
options | Rule_options.t | Options de fonctionnalites moteur par regle |
12.3 Range_with_metavars.t (resultat de match)
| Champ | Description |
|---|---|
range | Plage d’octets (start_pos, end_pos) dans le fichier source |
mvars | Liste de liaisons (mvar_name, AST_node) |
origin | Rule_ID qui a produit ce match |
taint_trace | Chemin de provenance source-to-sink (mode taint uniquement) |
fix | Chaine d’autofix calculee (si la regle a fix:) |
Annexe A : Couverture des parsers
| Backend | Langages |
|---|---|
| Tree-sitter | Go, Java, JavaScript, TypeScript, C, C++, C#, Kotlin, Ruby, Rust, Scala, Swift, HCL, Dockerfile, JSON, YAML, HTML, Bash, … |
| Pfff | Python, PHP, OCaml (legacy) |
| Custom / Mixed | Generic (tout langage via Spacegrep / Aliengrep) |
Annexe B : Glossaire
| Terme | Definition |
|---|---|
| AST_generic | L’AST universel de Semgrep – une representation normalisee du code de n’importe quel langage |
| IL | Intermediate Language – une forme aplatie a 3 adresses du corps d’une fonction |
| CFG | Control Flow Graph – les noeuds sont des instructions IL ; les aretes sont des chemins d’execution |
| Metavariable | Wildcard de pattern (par ex., $X) qui se lie aux noeuds AST matches |
| Taint | Un label marquant des donnees provenant d’une source dangereuse |
| Fixpoint | Le point stable d’une boucle d’iteration de dataflow (plus aucun changement d’etat) |
| Prefilter | Scan d’exclusion par fichier base sur les chaines litterales extraites des patterns de regles |
| OSemgrep | Reimplementation en OCaml du CLI semgrep (remplace pysemgrep) |
| Pro engine | Moteur commercial de Semgrep ajoutant l’analyse inter-procedurale et cross-file |
| SCA | Software Composition Analysis – analyse des manifestes de paquets pour les CVE connues |
| SARIF | Static Analysis Results Interchange Format – schema de sortie JSON standardise |