À propos de la création de suites de requêtes CodeQL
Remarque : cet article décrit les fonctionnalités disponibles avec l’offre groupée CodeQL CLI 2.18.4 incluse dans la mise en production initiale de GitHub Enterprise Server 3.15.
Si votre administrateur de site a mis à jour votre versionCodeQL CLI vers une version plus récente, consultez la version GitHub Enterprise Cloud de cet article pour obtenir plus d’informations sur les dernières fonctionnalités.
Les suites de requêtes CodeQL permettent de sélectionner des requêtes, en fonction de leur nom de fichier, de leur emplacement sur le disque ou dans un pack CodeQL, ou de propriétés des métadonnées. Créez des suites de requêtes pour les requêtes que vous voulez utiliser fréquemment dans vos analyses CodeQL.
Les suites de requêtes vous permettent de passer plusieurs requêtes à CodeQL sans devoir spécifier individuellement le chemin de chaque fichier de requête. Les définitions de suite de requêtes sont stockées dans des fichiers YAML avec l’extension .qls
. Une définition de suite est une séquence d’instructions, où chaque instruction est un mappage YAML avec (en général) une clé unique. Les instructions sont exécutées dans l’ordre dans lequel elles apparaissent dans la définition de la suite de requêtes. Une fois que toutes les instructions de la définition de la suite ont été exécutées, le résultat est un ensemble de requêtes sélectionnées.
Remarque : les requêtes personnalisées que vous voulez ajouter à une suite de requêtes doivent se trouver dans un pack CodeQL et contenir les métadonnées de requête correctes. Pour plus d’informations, consultez « Utilisation de requêtes personnalisées avec CodeQL CLI ».
Localisation des requêtes à ajouter à une suite de requêtes
Lors de la création d’une suite de requêtes, vous devez d’abord spécifier les emplacements des requêtes que vous voulez sélectionner. Vous pouvez définir l’emplacement d’une ou plusieurs requêtes en utilisant :
-
Une instruction
query
- indique à CodeQL de rechercher un ou plusieurs fichiers.ql
spécifiés :- query: <path-to-query>
L’argument doit être un ou plusieurs chemins de fichier, relativement au pack CodeQL contenant la définition de la suite.
-
Une instruction
queries
- indique à CodeQL de parcourir un répertoire de façon récursive pour y rechercher des fichiers.ql
:- queries: <path-to-subdirectory>
Le chemin du répertoire doit être relatif à la racine du pack CodeQL qui contient le fichier de définition de la suite. Pour rechercher les requêtes relatives à un autre pack CodeQL, ajoutez un champ
from
:- queries: <path-to-subdirectory> from: <ql-pack-name> version: ^x.y.z
Le champ
version
est facultatif et spécifie une plage de versions compatibles de ce pack CodeQL. Si vous ne spécifiez pas de version, la version la plus récente du pack est utilisée. -
Une instruction
qlpack
- indique à CodeQL de résoudre les requêtes dans la suite par défaut du pack CodeQL nommé :- qlpack: <qlpack-name> version: ^x.y.z
La suite par défaut d’un pack de requêtes comprend un ensemble recommandé de requêtes au sein de ce pack de requêtes. Tous les packs de requêtes n’ont pas une suite par défaut. Si le pack de requêtes donné ne définit pas de suite par défaut, l’instruction qlpack va avoir comme résultat toutes les requêtes du pack.
Le champ
version
est facultatif et spécifie une plage de versions compatibles de ce pack CodeQL. Si vous ne spécifiez pas de version, la version la plus récente du pack est utilisée.
Remarque : Quand des noms de chemin apparaissent dans les définitions d’une suite de requêtes, ils doivent toujours être indiqués avec une barre oblique /
comme séparateur de répertoires. Ceci garantit que les définitions de suite de requêtes fonctionnent sur tous les systèmes d’exploitation.
Vous devez ajouter au moins une instruction query
, queries
ou qlpack
à votre définition de suite, sinon aucune requête ne sera sélectionnée. Si la suite ne contient pas d’autres instructions, toutes les requêtes trouvées dans la liste des fichiers, dans le répertoire donné ou dans le pack CodeQL nommé sont sélectionnées. S’il existe d’autres instructions de filtrage, seules les requêtes qui correspondent aux contraintes imposées par ces instructions seront sélectionnées.
Filtrage des requêtes dans une suite de requêtes
Après avoir défini l’ensemble initial de requêtes à ajouter à votre suite en spécifiant des instructions query
, queries
ou qlpack
, vous pouvez ajouter des instructions include
et exclude
. Ces instructions définissent des critères de sélection basés sur des propriétés spécifiques :
- Quand vous exécutez une instruction
include
sur un ensemble de requêtes, toutes les requêtes qui correspondent à vos conditions sont conservées dans la sélection, et les requêtes qui ne correspondent pas sont retirées. - Quand vous exécutez une instruction
exclude
sur un ensemble de requêtes, toutes les requêtes qui correspondent à vos conditions sont retirées de la sélection et les requêtes qui n’y correspondent pas sont conservées.
L’ordre de vos instructions de filtrage est important. La première instruction de filtrage qui apparaît après les instructions relatives aux emplacements détermine si les requêtes sont incluses ou exclues par défaut. Si le premier filtre est un include
, les requêtes initialement sélectionnées sur la base de leur emplacement font partie de la suite seulement si elles correspondent à un filtre include
explicite. Si le premier filtre est un exclude
, les requêtes initialement sélectionnées sur la base de leur emplacement font partie de la suite à moins d’être explicitement exclues.
Les instructions suivantes sont exécutées dans l’ordre et les instructions qui apparaissent plus tard dans le fichier sont prioritaires sur les instructions précédentes. Ainsi, les instructions include
peuvent être remplacées par des instructions exclude
ultérieures qui correspondent à la même requête. De même, des instructions exclude
peuvent être remplacées par une instruction include
ultérieure.
Pour les deux instructions, l’argument est un bloc de contraintes, c’est-à-dire un mappage YAML représentant les contraintes. Chaque contrainte est une entrée de mappage, où la clé est généralement une propriété de métadonnées de requête. La valeur peut être :
- Une seule chaîne.
- Une expression régulière entre des
/
. - Une liste contenant des chaînes, des expressions régulières ou les deux.
Pour correspondre à une contrainte, une valeur de métadonnées doit correspondre à une des chaînes ou des expressions régulières. Quand il existe plusieurs clés de métadonnées, chaque clé doit correspondre.
Les clés de métadonnées standard disponibles pour la mise en correspondance sont : description
, id
, kind
, name
, tags
, precision
et problem.severity
.
Pour plus d’informations sur les propriétés de métadonnées de requête, consultez « Métadonnées pour les requêtes CodeQL ».
En plus des étiquettes de métadonnées, les clés du bloc de contraintes peuvent également être :
query filename
- correspond au dernier composant du chemin du nom de fichier de la requête.query path
- correspond au chemin du fichier de la requête relativement au pack CodeQL qui la contient.tags contain
- une des chaînes de correspondance spécifiées doit correspondre à un des composants séparés par un espace de la valeur de la propriété de métadonnées@tags
.tags contain all
- chacune des chaînes de correspondance spécifiées doit correspondre à un des composants de la propriété de métadonnées@tags
.
Exemples de filtrage des requêtes exécutées
Un cas d’usage courant est de créer une suite de requêtes qui exécute toutes les requêtes d’un pack CodeQL, à l’exception de quelques requêtes spécifiques que l’utilisateur ne veut pas exécuter. D’une façon générale, nous vous recommandons de filtrer sur l’id
de requête, qui est un identificateur unique et stable pour chaque requête. Les trois définitions de suite de requêtes suivantes sont sémantiquement identiques et filtrent par id
de requête :
Ce filtre correspond à toutes les requêtes de la suite par défaut de codeql/cpp-queries
, à l’exception des deux requêtes ayant les identificateurs exclus :
- qlpack: codeql/cpp-queries
- exclude:
id:
- cpp/cleartext-transmission
- cpp/cleartext-storage-file
Dans cet exemple, une instruction exclude
distincte est utilisée pour chaque requête :
- qlpack: codeql/cpp-queries
- exclude:
id: cpp/cleartext-transmission
- exclude:
id: cpp/cleartext-storage-file
Dans cet exemple, une expression régulière exclut les deux mêmes requêtes. Elle exclut également toutes les requêtes futures ajoutées à la suite avec des identificateurs qui commencent par cpp/cleartext-
:
- qlpack: codeql/cpp-queries
- exclude:
id:
- /^cpp\/cleartext-.*/
Pour définir une suite qui sélectionne toutes les requêtes dans la suite par défaut du pack CodeQL codeql/cpp-queries
, puis les affine pour inclure seulement les requêtes de sécurité, utilisez :
- qlpack: codeql/cpp-queries
- include:
tags contain: security
Pour définir une suite qui sélectionne toutes les requêtes avec @kind problem
et @precision high
dans le répertoire my-custom-queries
, utilisez :
- queries: my-custom-queries
- include:
kind: problem
precision: very-high
Notez que la définition de suite de requêtes suivante se comporte différemment de la définition ci-dessus. Cette définition sélectionne les requêtes qui sont @kind problem
ou sont @precision very-high
:
- queries: my-custom-queries
- include:
kind: problem
- include:
precision: very-high
Pour créer une suite qui sélectionne toutes les requêtes avec @kind problem
dans le répertoire my-custom-queries
à l’exception de celles avec @problem.severity recommendation
, utilisez :
- queries: my-custom-queries
- include:
kind: problem
- exclude:
problem.severity: recommendation
Pour créer une suite qui sélectionne toutes les requêtes avec @tag security
et @precision high
ou very-high
dans le pack CodeQL codeql/cpp-queries
, utilisez :
- queries: .
from: codeql/cpp-queries
- include:
tags contain: security
precision:
- high
- very-high
Remarque : Vous pouvez utiliser la commande codeql resolve queries /path/to/suite.qls
pour voir quelles requêtes sont sélectionnées par une définition de suite de requêtes. Pour plus d’informations, consultez « resolve queries ».
Réutilisation de définitions de suite de requêtes existantes
Les définitions de suite de requêtes existantes peuvent être réutilisées en spécifiant :
-
Une instruction
import
- ajoute les requêtes sélectionnées par un fichier.qls
précédemment défini à la suite actuelle :- import: <path-to-query-suite>
Le chemin de la suite importée doit être relatif au pack CodeQL contenant la définition actuelle de la suite. Si la suite de requêtes importée se trouve dans un autre pack QL, vous pouvez utiliser :
- import: <path-to-query-suite> from: <ql-pack> version: ^x.y.z
Le champ
version
est facultatif et spécifie une plage de versions compatibles de ce pack CodeQL. Si vous ne spécifiez pas de version, la version la plus récente du pack est utilisée.Les requêtes ajoutées avec une instruction
import
peuvent être filtrées en utilisant des instructionsexclude
ultérieures. -
Une instruction
apply
- ajoute toutes les instructions d’un fichier.qls
défini précédemment à la suite actuelle. Les instructions du fichier.qls
appliqué sont exécutées comme si elles se trouvaient à la place deapply
. Les instructionsinclude
etexclude
de la suite appliquée agissent également sur les requêtes ajoutées par les instructions antérieures :- apply: <path-to-query-suite>
L’instruction
apply
peut aussi être utilisée pour appliquer à plusieurs définitions de requête un ensemble de conditions réutilisables, enregistrées dans un fichier.yml
. Pour plus d’informations, consultez les exemples ci-dessous.
Exemples de réutilisabilité
Pour utiliser les mêmes conditions dans plusieurs définitions de suite de requêtes, créez un fichier .yml
distinct contenant vos instructions. Par exemple, enregistrez ceci dans un fichier appelé reusable-instructions.yml
:
- include:
kind:
- problem
- path-problem
tags contain: security
precision:
- high
- very-high
Ajoutez reusable-instructions.yml
au même pack CodeQL que votre suite de requêtes actuelle. Ensuite, dans une ou plusieurs suites de requêtes, utilisez l’instruction apply
pour appliquer les instructions réutilisables à la suite active. Par exemple :
- queries: queries/cpp/custom
- apply: reusable-instructions.yml
Ceci filtre les requêtes dans queries/cpp/custom
pour inclure seulement celles qui correspondent aux conditions réutilisables.
Vous pouvez aussi créer une définition de suite en utilisant reusable-instructions.yml
sur les requêtes d’un autre pack CodeQL. Si le fichier .qls
se trouve dans le même pack CodeQL que les requêtes, vous pouvez ajouter un champ from
immédiatement après l’instruction apply
:
# load queries from the default suite of my-org/my-other-custom-queries
- qlpack: my-org/my-other-custom-queries
# apply the reusable instructions from the my-org/my-custom-instructions CodeQL pack
- apply: reusable-instructions.yml
from: my-org/my-custom-instructions
version: ^1.2.3 # optional
Un cas d’usage courant pour une instruction import
est d’appliquer un filtre supplémentaire aux requêtes d’une autre suite de requêtes. Par exemple, cette suite va appliquer un filtrage supplémentaire à la suite cpp-security-and-quality
, et exclure les requêtes de précision low
et medium
:
- import: codeql-suites/cpp-security-and-quality.qls
from: codeql/cpp-queries
- exclude:
precision:
- low
- medium
Si vous voulez faire un include
des requêtes importées depuis une autre suite, la syntaxe est légèrement différente :
- import: codeql-suites/cpp-security-and-quality.qls
from: codeql/cpp-queries
- exclude: {}
- include:
precision:
- very-high
- high
Notez l’instruction exclude
vide. Ceci est nécessaire pour garantir que l’instruction include
qui suit est en mesure de filtrer les requêtes de la suite importée.
Nommage d’une suite de requêtes
Vous pouvez fournir un nom pour votre suite de requêtes en spécifiant une instruction description
:
- description: <name-of-query-suite>
Enregistrement d’une suite de requêtes
Enregistrez votre suite de requêtes dans un fichier avec une extension .qls
et ajoutez-la à un pack CodeQL. Pour plus d’informations, consultez « Personnalisation de l’analyse avec des packs CodeQL ».
Utilisation de suites de requêtes avec CodeQL
Vous pouvez spécifier des suites de requêtes sur la ligne de commande pour les commandes qui acceptent des fichiers .qls
. Par exemple, vous pouvez compiler les requêtes sélectionnées par une définition de suite en utilisant query compile
ou utiliser les requêtes dans une analyse en utilisant database analyze
. Pour plus d’informations sur l’analyse de bases de données CodeQL, consultez « Analyse de votre code avec des requêtes CodeQL ».
Pour aller plus loin
- « Requêtes CodeQL »