Skip to main content

CrĂ©ation de suites de requĂȘtes CodeQL

Vous pouvez crĂ©er des suites de requĂȘtes pour les requĂȘtes que vous utilisez frĂ©quemment dans vos analyses CodeQL.

Qui peut utiliser cette fonctionnalité ?

CodeQL est disponible pour les types de rĂ©fĂ©rentiels suivants :

À propos de la crĂ©ation de suites de requĂȘtes CodeQL

Remarque

Cet article décrit les fonctionnalités disponibles avec le pack CodeQL CLI 2.20.7 inclus dans la mise en production initiale de GitHub Enterprise Server 3.17.

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 rechercher rĂ©cursivement des fichiers .ql dans un rĂ©pertoire :

    - 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 nommĂ© CodeQL :

    - 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 Ă  la derniĂšre composante du chemin d'accĂšs du nom du fichier de la requĂȘte.
  • query path: Correspond au chemin d'accĂšs au fichier de requĂȘte par rapport au paquet CodeQL qui l'entoure.
  • tags contain: L'une des chaĂźnes de correspondance donnĂ©es doit correspondre Ă  l'un des composants sĂ©parĂ©s par des espaces de la valeur de la propriĂ©tĂ© de mĂ©tadonnĂ©es @tags.
  • tags contain all: Chacune des chaĂźnes de correspondance donnĂ©es doit correspondre Ă  l'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 instructions exclude ultĂ©rieures.

  • Une instruction apply : Ajoute toutes les instructions d'un fichier .qls prĂ©cĂ©demment dĂ©fini Ă  la suite actuelle. Les instructions du fichier .qls appliquĂ© sont exĂ©cutĂ©es comme si elles se trouvaient Ă  la place de apply. Les instructions include et exclude 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