Préparer une base de données pour CodeQL
CodeQL traite le code comme les données. L’analyse CodeQL s’appuie sur l’extraction de données relationnelles à partir de votre code et son utilisation pour générer une base de données CodeQL. Ces bases de données contiennent toutes les informations importantes relatives à une base de code.
Vous pouvez ensuite exécuter des requêtes CodeQL sur cette base de données pour identifier les vulnérabilités de sécurité, les bogues et d’autres erreurs. Vous pouvez écrire vos propres requêtes ou exécuter des requêtes CodeQL standard écrites par des chercheurs GitHub et des contributeurs de la communauté.
Vous pouvez utiliser l’interface CLI CodeQL autonome pour créer et analyser une base de données CodeQL. L’analyse de la base de données génère des résultats au format SARIF (Static Analysis Results Interchange Format), qui peut être chargé dans un référentiel GitHub pour afficher les détails de l’alerte.
Architecture d’analyse CodeQL
L’analyse CodeQL suit un pipeline qui transforme le code source en données interrogeables, exécute des requêtes de sécurité et publie les résultats en tant qu’alertes d’analyse du code.
Le flux de travail d’analyse est le suivant :
- Code source : CodeQL part du contenu du dépôt au niveau du commit analysé.
- Extraction : Un extracteur spécifique au langage lit le code et collecte des faits sur les fichiers sources, la syntaxe, le flux de contrôle et le flux de données.
- Création de base de données : Les faits extraits sont stockés dans une base de données CodeQL. Chaque base de données représente une langue dans la base de code.
- Exécution de requête : CodeQL exécute des requêtes gérées GitHub, des requêtes communautaires ou des requêtes personnalisées sur la base de données.
- Génération SARIF : Les résultats de la requête sont écrits au format SARIF (Static Analysis Results Interchange Format).
- GitHub analyse du code : les résultats SARIF sont chargés dans GitHub et affichés en tant qu’alertes d’analyse du code.
Cette architecture sépare l’extraction de code de l’exécution des requêtes. Une fois qu’une base de données a été créée, vous pouvez exécuter différentes suites de requêtes sur la même base de données sans extraire à nouveau le code.
Stratégie de langage
CodeQL prend en charge les langages compilés et interprétés, mais la stratégie d’extraction dépend du type de langage.
Langues compilées
Pour les langages compilés tels que :
- C/C++
- C#
- Java
- Kotlin
- Rust
- Swift
- Allez
CodeQL doit souvent comprendre comment le projet est compilé. Lors de la création de la base de données, CodeQL peut surveiller le processus de génération afin qu’il puisse extraire les fichiers sources traités par le compilateur.
Pour obtenir les résultats les plus fiables, configurez des commandes de compilation explicites plutôt que de vous fier à génération automatique ou à l’option sans compilation.
Langages interprétés
Pour les langages interprétés tels que :
- Python
- JavaScript/TypeScript
- Ruby
CodeQL extrait des informations directement à partir du code source sans nécessiter de commande de build distincte.
Référentiels multilingues
Pour les référentiels contenant plusieurs langues prises en charge :
- Créez une base de données distincte pour chaque langue.
- Dans GitHub Actions, utilisez une matrice de langage pour que chaque langage soit initialisé, extrait et analysé correctement.
Préparation de la base de données pour CodeQL
Avant de générer une base de données CodeQL :
- Installez et configurez l’interface CLI CodeQL.
- Consultez la version de la base de code que vous souhaitez analyser.
Pour les langues compilées :
- Assurez-vous que le projet est prêt pour le build.
- Installez toutes les dépendances requises au préalable.
- CodeQL extrait une représentation relationnelle de chaque fichier source pour créer la base de données.
Pour les langages interprétés :
- L’extracteur s’exécute directement sur le code source.
- Les dépendances sont résolues automatiquement lors de l’extraction.
Pour les langages compilés, CodeQL surveille le processus de génération normal. Chaque fois que le compilateur traite un fichier source, CodeQL crée une copie et extrait toutes les informations pertinentes requises pour l’analyse.
Configuration de l’interface CLI
Suivez ces étapes pour installer l’interface CLI CodeQL.
1. Télécharger le bundle CLI CodeQL
La méthode d’installation recommandée télécharge le package groupé, qui garantit la compatibilité entre l’interface CLI, les bibliothèques et les packs de requêtes.
L’offre groupée comprend :
- L’interface de ligne de commande CodeQL
- Requêtes et bibliothèques CodeQL compatibles
- Packs de requêtes précompilés
Pour télécharger le bundle :
- Accédez à la page Releases du référentiel public CodeQL.
- Téléchargez l’offre groupée spécifique à la plateforme sous Ressources.
La page Versions inclut également :
- Notes de publication
- Versions précédentes
-
codeql-bundle.tar.gz, qui prend en charge toutes les plateformes
2. Extraire l’archive
Extrayez l’archive .zip dans un répertoire de votre choix.
Les utilisateurs de macOS Catalina (ou version ultérieure) doivent effectuer des étapes de configuration supplémentaires, comme décrit dans la documentation de l’interface CLI CodeQL.
3. Exécuter CodeQL
Après l’extraction, au choix :
- Run:
<extraction-root>/codeql/codeql
ou
- Ajouter :
<extraction-root>/codeql
sur votre système PATH afin que vous puissiez invoquer la CLI simplement comme suit :
codeql
Vous pouvez maintenant exécuter des commandes CodeQL.
Vérifier la configuration de votre interface CLI
Exécutez les commandes suivantes pour vérifier que votre installation fonctionne correctement.
Afficher les packs CodeQL installés :
codeql resolve packs
Si l’exécutable n’est pas dans votre PATH, utilisez :
<extraction-root>/codeql/codeql resolve packs
Si les modules linguistiques attendus sont manquants, vérifiez que vous avez téléchargé le bundle CodeQL, et non l’interface CLI autonome.
Afficher les langues prises en charge :
codeql resolve languages
Création de base de données
Créez une base de données CodeQL à partir de la racine de votre projet :
codeql database create <database> --language=<language-identifier>
Remplacez :
-
<database>avec le répertoire de destination. -
<language-identifier>avec l’identifiant de la langue à analyser.
Vous pouvez également utiliser les options suivantes :
| Option | Purpose |
|---|---|
--source-root |
Spécifie le répertoire racine contenant le code source. |
--db-cluster |
Crée des bases de données pour plusieurs langues. |
--command |
Spécifie la commande de build pour les langues compilées. Non requis pour Python, Ruby ou JavaScript. |
--no-run-unnecessary-builds |
Ignore les builds inutiles lorsqu’elles sont utilisées avec --db-cluster. |
Une fois l’exécution réussie :
- Un répertoire de base de données est créé.
- Lors de l’utilisation
--db-cluster, un sous-répertoire est créé pour chaque langue.
Chaque base de données contient :
- Données d’analyse relationnelle
- Archive des sources
- Métadonnées requises pour l’analyse CodeQL
L’archive source est un instantané des fichiers sources au moment de la création de la base de données et est utilisé lors de l’affichage des résultats d’analyse.
Considérations relatives à la génération et aux performances de la base de données
Après avoir créé une base de données CodeQL, il est important de comprendre le fonctionnement de la génération de base de données et son impact sur les performances.
Méthodes de génération de base de données
Vous pouvez générer des bases de données CodeQL à l’aide des éléments suivants :
Interface de ligne de commande CLI CodeQL
Créez des bases de données et exécutez l’analyse manuellement.
Cette approche est utile pour :
- Développement local
- Debugging
- Configurations avancées
Flux de travail GitHub Actions
La plupart des organisations automatisent la génération de base de données via GitHub Actions.
Un flux de travail classique :
- Initialise CodeQL.
- Crée des bases de données.
- Exécute des requêtes.
- Charge les résultats SARIF dans GitHub.
Bases de données par langue
CodeQL crée une base de données distincte pour chaque langage pris en charge.
Chaque langue :
- Utilise son propre extracteur.
- Utilise son propre schéma de base de données.
- Est analysé indépendamment.
Pour les référentiels multi-langages, soit :
- Utilisez l’option
--db-clusteravec l’interface de ligne de commande. - Configurez une matrice de langage dans GitHub Actions.
Une matrice de langage permet une analyse parallèle et une couverture linguistique complète.
Extraction basée sur la compilation pour les langages compilés
Pour les langues compilées :
- CodeQL surveille le processus de génération.
- Le build doit se terminer avec succès.
- La fonctionnalité autobuild ne fonctionne pas de manière fiable pour tous les projets.
Pour obtenir les meilleurs résultats, définissez les étapes de génération explicites avant l’analyse.
Pour les langages interprétés, CodeQL extrait directement du code source sans nécessiter de build.
Considérations relatives aux performances
La création et le temps d’analyse de la base de données dépendent de plusieurs facteurs.
Taille du référentiel
Les dépôts plus volumineux nécessitent davantage d’extraction et de temps d’analyse.
Langues multiples
Utilisez une matrice de langage pour analyser les langages en parallèle et réduire le runtime total.
Ressources CI
L’analyse CodeQL peut être gourmande en ressources.
Augmenter le processeur ou la mémoire des runners peut considérablement améliorer les performances.
Étendue de l’analyse
Vous pouvez réduire le temps d’analyse en limitant le code analysé, par exemple en excluant :
- Fichiers de test
- Code généré
En général, le temps d’analyse est proportionnel à la quantité de code source en cours de traitement.
Création et régénération de bases de données
Une base de données CodeQL représente un instantané de la base de code à un point spécifique dans le temps.
- Une nouvelle base de données est créée pour chaque exécution d’analyse.
- Les bases de données ne sont pas mises à jour de manière incrémentielle.
- Toute modification apportée à la base de code nécessite une nouvelle base de données.
Vous régénérez généralement les bases de données quand :
- De nouveaux commits sont envoyés.
- Les pull requests sont ouvertes ou mises à jour.
- Modifications de configuration de build.
- Modifications de configuration des jeux de requêtes ou de l’analyse.
Étant donné que la génération de base de données fait partie de chaque analyse, il est important d’aligner les analyses avec des événements significatifs, tels que les demandes d’extraction ou les exécutions planifiées.
Extracteurs
Un extracteur est un outil qui produit les données relationnelles et la référence source pour chaque fichier d’entrée, à partir duquel une base de données CodeQL peut être générée. Chaque langage pris en charge par CodeQL a un extracteur. Cette structure garantit que le processus d’extraction est aussi précis que possible.
Chaque extracteur définit son propre ensemble d’options de configuration. La saisie de codeql resolve extractor --format=betterjson génère des données formatées comme dans l’exemple suivant :
{
"extractor_root": "/home/user/codeql/java",
"extractor_options": {
"option1": {
"title": "Java extractor option 1",
"description": "An example string option for the Java extractor.",
"type": "string",
"pattern": "[a-z]+"
},
"group1": {
"title": "Java extractor group 1",
"description": "An example option group for the Java extractor.",
"type": "object",
"properties": {
"option2": {
"title": "Java extractor option 2",
"description": "An example array option for the Java extractor",
"type": "array",
"pattern": "[1-9][0-9]*"
}
}
}
}
}
Pour savoir quelles options sont disponibles pour l’extracteur de votre langue, entrez :
-
codeql resolve languages --format=betterjsonou -
codeql resolve extractor --format=betterjson.
Le format de sortie betterjson fournit également la racine de l’extracteur et d’autres options spécifiques au langage.
Données dans une base de données CodeQL
Une base de données CodeQL est un répertoire unique qui contient toutes les données requises pour l’analyse. Ces données incluent des données relationnelles, des fichiers sources copiés et un schéma de base de données spécifique au langage qui spécifie les relations mutuelles dans les données. CodeQL importe ces données après l’extraction.
Les bases de données CodeQL fournissent un instantané des données interrogeables d’un langage particulier extraites d’une base de code. Ces données sont une représentation hiérarchique complète du code. Il inclut :
- Représentation de l’arborescence de syntaxe abstraite (AST).
- Graphique de flux de données.
- Graphique de flux de contrôle.
Les bases de données sont générées une langue à la fois pour les bases de code en plusieurs langues. Chaque langage a son propre schéma de base de données unique. Le schéma fournit une interface entre l’analyse lexicale initiale pendant le processus d’extraction et l’analyse complexe via CodeQL.
Une base de données CodeQL comprend deux tables principales :
- La table d’expressions contient une ligne pour chaque expression dans le code source analysé par CodeQL pendant le processus de génération.
- La table d’instructions contient une ligne pour chaque instruction du code source analysé par CodeQL pendant le processus de génération.
La bibliothèque CodeQL définit des classes pour fournir une couche d’abstraction sur chacune de ces tables. Cette couche inclut les tables auxiliaires associées Expr et Stmt.
Lacunes potentielles de CodeQL
La création de bases de données dans le flux de travail d’analyse du code présente des lacunes potentielles. Cette section traite spécifiquement de l’utilisation de l’action codeQL GitHub.
Vous devez utiliser une matrice de langage pour générer automatiquement chacune des langues compilées répertoriées dans la matrice. Vous pouvez utiliser une matrice pour créer des travaux pour plusieurs versions prises en charge d’un langage de programmation, d’un système d’exploitation ou d’un outil.
Si vous n’utilisez pas de matrice, la génération automatique tente de générer le langage compilé pris en charge avec les fichiers sources les plus présents dans le référentiel. L’analyse des langages compilés, autres que Go, échoue souvent, sauf si vous fournissez des commandes explicites pour générer le code avant d’effectuer l’étape d’analyse.
Le comportement de l’étape de génération automatique varie en fonction du système d’exploitation sur lequel s’exécute l’extracteur de langage. L’étape de génération automatique tente de détecter automatiquement une méthode de génération appropriée pour la langue en fonction du système d’exploitation. Ce comportement peut entraîner des résultats non fiables pour les langages compilés et peut souvent entraîner une exécution ayant échoué.
Nous vous recommandons de configurer une étape de compilation dans le fichier de workflow d’analyse du code, qui s’exécute avant l’analyse, plutôt que de laisser la fonctionnalité Autobuild tenter de compiler les langages compilés. De cette façon, le fichier de flux de travail est adapté aux exigences de build de votre système et du projet pour des analyses plus fiables.
Vous pouvez en savoir plus sur des langages spécifiques et les étapes de génération automatique dans la documentation de la génération automatique CodeQL.
Extension VS Code
Vous pouvez utiliser Visual Studio Code (VS Code) et l’extension CodeQL pour compiler et exécuter des requêtes, tant que vous utilisez VS Code 1.39 ou version ultérieure. Vous pouvez télécharger l’extension à partir de la Place de marché Visual Studio Code ou en téléchargeant le fichier VSIX CodeQL.
L’extension utilise votre interface CLI installée dans PATH le cas où elle est disponible. Si ce n’est pas le cas, l’extension gère automatiquement l’accès au fichier exécutable de l’interface CLI pour vous. La gestion automatique garantit que l’interface CLI est compatible avec l’extension CodeQL.