Подготовка базы данных для CodeQL

Завершено

CodeQL обрабатывает код как данные. Анализ CodeQL использует извлечение реляционных данных из кода и его использование для создания базы данных CodeQL. Эти базы данных содержат все важные сведения о базе кода.

Затем вы можете выполнить запросы CodeQL к этой базе данных, чтобы определить уязвимости безопасности, ошибки и другие ошибки. Вы можете создавать собственные запросы или выполнять стандартные запросы CodeQL, написанные исследователями GitHub и участниками сообщества.

Вы можете использовать автономный интерфейс командной строки CodeQL для создания и анализа базы данных CodeQL. Анализ базы данных создает результаты в формате обмена статическими результатами анализа (SARIF), который можно отправить в репозиторий GitHub для просмотра сведений об оповещении.

Архитектура сканирования CodeQL

Сканирование CodeQL следует конвейеру, который преобразует исходный код в запрашиваемые данные, выполняет запросы безопасности и публикует результаты в виде оповещений сканирования кода.

Рабочий процесс сканирования:

  1. Исходный код: CodeQL использует содержимое репозитория на анализируемом коммите.
  2. Извлечение: Языково-специфический экстрактор анализирует код и собирает сведения об исходных файлах, синтаксисе, потоке управления и потоке данных.
  3. Создание базы данных: Извлеченные факты хранятся в базе данных CodeQL. Каждая база данных представляет один язык в базе кода.
  4. Выполнение запроса: CodeQL выполняет GitHub поддерживаемые запросы, запросы сообщества или пользовательские запросы к базе данных.
  5. Создание SARIF: Результаты запроса записываются в формате обмена результатами статического анализа (SARIF).
  6. Сканирование кода в GitHub: Результаты SARIF загружаются в GitHub и отображаются как предупреждения сканирования кода.

Эта архитектура отделяет извлечение кода от выполнения запроса. После создания базы данных можно запустить различные наборы запросов к одной базе данных без повторного извлечения кода.

Стратегия языка

CodeQL поддерживает как скомпилированные, так и интерпретированные языки, но стратегия извлечения зависит от типа языка.

Компилированные языки

Для скомпилированных языков, таких как:

  • C/C++
  • C#
  • Java
  • Kotlin
  • Rust
  • Swift
  • Go

CodeQL часто требуется понимать, как собирается проект. Во время создания базы данных CodeQL может отслеживать процесс сборки, чтобы он мог извлечь исходные файлы, обработанные компилятором.

Чтобы получить наиболее надежные результаты, явно задайте команды сборки, вместо того чтобы полагаться на варианты автосборки или без сборки.

Интерпретируемые языки

Для интерпретированных языков, таких как:

  • Python
  • JavaScript/TypeScript
  • Ruby

CodeQL извлекает сведения непосредственно из исходного кода, не требуя отдельной команды сборки.

Репозитории с несколькими языками

Для репозиториев, содержащих несколько поддерживаемых языков:

  • Создайте отдельную базу данных для каждого языка.
  • В GitHub Actions используйте языковую матрицу, чтобы каждый язык инициализировался, извлекается и анализируется правильно.

Подготовка базы данных для CodeQL

Перед созданием базы данных CodeQL:

  1. Установите и настройте CLI CodeQL.
  2. Ознакомьтесь с версией базы кода, которую вы хотите проанализировать.

Для скомпилированных языков:

  • Убедитесь, что проект готов к сборке.
  • Заранее установите все необходимые зависимости.
  • CodeQL извлекает реляционное представление каждого исходного файла для создания базы данных.

Для интерпретированных языков:

  • Извлекатель работает напрямую с исходным кодом.
  • Зависимости разрешаются автоматически во время извлечения.

Для скомпилированных языков CodeQL отслеживает обычный процесс сборки. Каждый раз, когда компилятор обрабатывает исходный файл, CodeQL создает копию и извлекает все необходимые сведения, необходимые для анализа.

Настройка CLI

Выполните следующие действия, чтобы установить CLI CodeQL.

1. Скачивание пакета CLI CodeQL

Рекомендуемый метод установки загружает пакет, обеспечивающий совместимость между интерфейсом командной строки, библиотеками и пакетами запросов.

Пакет включает в себя следующее:

  • The CodeQL CLI
  • Совместимые запросы и библиотеки CodeQL
  • Предварительно скомпилированные пакеты запросов

Чтобы скачать пакет, выполните следующие действия.

  1. Перейдите на страницу выпусков общедоступного репозитория CodeQL.
  2. Скачайте пакет для конкретной платформы в разделе Ресурсы.

На странице "Выпуски" также содержится следующее:

  • Примечания к релизу
  • Предыдущие версии
  • codeql-bundle.tar.gz, который поддерживает все платформы

2. Извлечение архива

Извлеките архив .zip в выбранный вами каталог.

Пользователи macOS Catalina (или более поздней версии) должны выполнить дополнительные действия по настройке, как описано в документации по CLI CodeQL.

3. Запуск CodeQL

После извлечения выполните одно из следующих действий:

  • Запуск:
<extraction-root>/codeql/codeql

или

  • Добавьте:
<extraction-root>/codeql

в вашу систему PATH, чтобы затем можно было просто вызвать CLI следующим образом:

codeql

Теперь можно выполнять команды CodeQL.

Проверьте настройку CLI

Выполните следующие команды, чтобы убедиться, что установка работает правильно.

Отображение установленных пакетов CodeQL:

codeql resolve packs

Если исполняемый файл отсутствует в вашем PATH, используйте:

<extraction-root>/codeql/codeql resolve packs

Если ожидаемые языковые пакеты отсутствуют, убедитесь, что вы скачали пакет CodeQL, а не автономный интерфейс командной строки.

Отображение поддерживаемых языков:

codeql resolve languages

Создание базы данных

Создайте базу данных CodeQL в корневом каталоге вашего проекта:

codeql database create <database> --language=<language-identifier>

Замените:

  • <database> с целевым каталогом.
  • <language-identifier> с идентификатором анализируемого языка.

Вы также можете использовать следующие параметры:

Option Purpose
--source-root Указывает корневой каталог, содержащий исходный код.
--db-cluster Создает базы данных для нескольких языков.
--command Задает команду сборки для скомпилированных языков. Не требуется для Python, Ruby или JavaScript.
--no-run-unnecessary-builds Пропускает ненужные сборки при использовании --db-cluster.

После успешного выполнения:

  • Создается новый каталог базы данных.
  • При использовании --db-clusterдля каждого языка создается подкаталог.

Каждая база данных содержит следующее:

  • Данные реляционного анализа
  • Исходный архив
  • Метаданные, необходимые для анализа CodeQL

Исходный архив — это моментальный снимок исходных файлов во время создания базы данных и используется при отображении результатов анализа.

Вопросы создания и производительности базы данных

После создания базы данных CodeQL важно понять, как работает создание базы данных и как она влияет на производительность.

Методы создания базы данных

Базы данных CodeQL можно создавать с помощью следующих способов:

CodeQL CLI

Создайте базы данных и выполните анализ вручную.

Этот подход полезен для:

  • Местное развитие
  • Отладка
  • Расширенные конфигурации

рабочие процессы GitHub Actions

Большинство организаций автоматизируют создание баз данных с помощью GitHub Actions.

Типичный рабочий процесс:

  1. Инициализирует CodeQL.
  2. Создает базы данных.
  3. Выполняет запросы.
  4. Отправляет результаты SARIF в GitHub.

Базы данных для каждого языка

CodeQL создает отдельную базу данных для каждого поддерживаемого языка.

Каждый язык:

  • Использует собственное средство извлечения.
  • Использует собственную схему базы данных.
  • Анализируется независимо.

Для многоязычных репозиториев выполните одно из следующих действий:

  • Используйте параметр --db-cluster в CLI.
  • Настройте языковую матрицу в GitHub Actions.

Матрица языка обеспечивает параллельный анализ и полное покрытие языка.

Извлечение на основе сборки для скомпилированных языков

Для скомпилированных языков:

  • CodeQL отслеживает процесс сборки.
  • Сборка должна завершиться успешно.
  • Автоматическая автоматическая сборка не работает надежно для каждого проекта.

Для получения наилучших результатов определите явные шаги сборки перед анализом.

Для интерпретированных языков CodeQL извлекает непосредственно из исходного кода, не требуя сборки.

Вопросы производительности

Время создания и анализа базы данных зависит от нескольких факторов.

Размер репозитория

Для больших репозиториев требуется больше времени извлечения и анализа.

Несколько языков

Используйте матрицу языка для параллельного анализа языков и уменьшения общей среды выполнения.

Ресурсы CI

Анализ CodeQL может быть ресурсоемким.

Увеличение ресурсов ЦП или объёма памяти для раннеров может значительно повысить производительность.

Область анализа

Можно сократить время анализа, ограничив код, который сканируется, например, исключив:

  • Тестовые файлы
  • Созданный код

Как правило, время анализа пропорционально объему обрабатываемого исходного кода.

Создание и повторное создание базы данных

База данных CodeQL представляет моментальный снимок базы кода в определенный момент времени.

  • Для каждого выполнения анализа создается новая база данных.
  • Базы данных не обновляются постепенно.
  • Для любых изменений в базе кода требуется новая база данных.

Обычно при повторном создании баз данных выполняется следующее:

  • Новые фиксации отправляются.
  • Запросы на включение изменений открываются или обновляются.
  • Изменения конфигурации сборки.
  • Наборы запросов или изменения конфигурации анализа.

Поскольку создание базы данных является частью каждой проверки, важно соотносить проверки со значимыми событиями, такими как pull request’ы или плановые запуски.

Экстракторы

Средство извлечения — это средство, которое создает реляционные данные и ссылку на источник для каждого входного файла, из которого можно создать базу данных CodeQL. Каждый язык, поддерживаемый CodeQL, имеет один средство извлечения. Эта структура гарантирует, что процесс извлечения максимально точный.

Каждый инструмент извлечения определяет собственный набор параметров конфигурации. Ввод codeql resolve extractor --format=betterjson приводит к форматированию данных, как показано в следующем примере:

{
  "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]*"
        }
      }
    }
  }
}

Чтобы узнать, какие параметры доступны для средства извлечения языка, введите:

  • codeql resolve languages --format=betterjson, или
  • codeql resolve extractor --format=betterjson.

Формат выходных данных betterjson также предоставляет корень извлекателя и другие параметры, зависящие от языка.

Данные в базе данных CodeQL

База данных CodeQL — это один каталог, содержащий все данные, необходимые для анализа. Эти данные включают реляционные данные, скопированные исходные файлы и схему базы данных, зависящую от языка, которая указывает взаимные отношения в данных. CodeQL импортирует эти данные после извлечения.

Базы данных CodeQL предоставляют моментальный снимок запрашиваемых данных определенного языка, извлеченных из базы кода. Эти данные являются полным иерархическим представлением кода. Сюда входят:

  • Представление дерева абстрактного синтаксиса (AST).
  • Граф потока данных.
  • Граф потока управления.

Базы данных создаются на одном языке одновременно для баз кода с несколькими языками. Каждый язык имеет собственную уникальную схему базы данных. Схема предоставляет интерфейс между первоначальным лексическим анализом во время извлечения и сложным анализом с помощью CodeQL.

База данных CodeQL включает две основные таблицы:

  • Таблица выражений содержит строку для каждого выражения в исходном коде, анализируемом CodeQL во время процесса сборки.
  • Таблица инструкций содержит строку для каждой инструкции в исходном коде, проанализированном CodeQL во время процесса сборки.

Библиотека CodeQL определяет классы для предоставления уровня абстракции по каждой из этих таблиц. Этот слой включает связанные вспомогательные таблицы Expr и Stmt.

Потенциальные недостатки CodeQL

Создание базы данных в рабочем процессе сканирования кода имеет некоторые потенциальные недостатки. В этом разделе описывается использование действия GitHub CodeQL.

Для autobuild необходимо использовать матрицу языков, чтобы собрать каждый из компилируемых языков, перечисленных в этой матрице. Матрицу можно использовать для создания заданий для нескольких поддерживаемых версий языка программирования, операционной системы или средства.

Если матрица не используется, autobuild пытается создать поддерживаемый скомпилированный язык с наиболее исходными файлами в репозитории. Анализ скомпилированных языков, отличных от Go, часто завершается ошибкой, если вы не предоставляете явные команды для сборки кода перед выполнением шага анализа.

Поведение этапа автоматической сборки зависит от операционной системы, на которой работает средство извлечения языка. Шаг автосборки пытается автоматически определить подходящий способ сборки для данного языка в зависимости от операционной системы. Это поведение может привести к ненадежным результатам для скомпилированных языков и часто может привести к сбою выполнения.

Рекомендуется настроить шаг сборки в файле рабочего процесса сканирования кода, который выполняется перед анализом, а не разрешить автострою пытаться создать скомпилированные языки. Таким образом, файл рабочего процесса адаптирован к требованиям к сборке системы и проекта для более надежных проверок.

Дополнительные сведения о конкретных языках и этапах автоматической сборки см. в документации CodeQL по автоматической сборке.

Расширение VS Code

Вы можете использовать Visual Studio Code (VS Code) и расширение CodeQL для компиляции и выполнения запросов, если вы используете VS Code 1.39 или более поздней версии. Расширение можно скачать из Visual Studio Code Marketplace или скачать файл CodeQL VSIX.

Расширение использует установленный интерфейс командной строки, найденный в PATH, если он доступен. В противном случае расширение автоматически управляет доступом к исполняемому файлу интерфейса командной строки. Автоматическое управление гарантирует совместимость интерфейса командной строки с расширением CodeQL.