Используйте CodeQL CLI

Завершено

Помимо графического пользовательского интерфейса в GitHub.com, вы также можете получить доступ ко многим из одних и того же основного компонента CodeQL через интерфейс командной строки.

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

Команды CodeQL CLI

После того как вы сделали CLI CodeQL доступным для серверов в вашей системе CI и убедились, что они могут аутентифицироваться в GitHub, вы готовы к созданию данных.

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

  • database create для создания базы данных CodeQL для представления иерархической структуры каждого поддерживаемого языка программирования в репозитории.
  • database analyze для запуска запросов, предназначенных для анализа каждой базы данных CodeQL, и сведения результатов в файл SARIF.
  • github upload-results для отправки результирующих файлов SARIF на GitHub, где результаты сопоставляются с ветвью или пулл-реквестом и отображаются в виде предупреждений проверки кода.

Можно с помощью --help option отобразить справку командной строки для любой команды.

Отправка данных SARIF для отображения в виде результатов сканирования кода в GitHub поддерживается для репозиториев, принадлежащих организации, с включенным GitHub Advanced Security и общедоступными репозиториями на GitHub.com.

Создание баз данных CodeQL для анализа

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

  1. Ознакомьтесь с кодом, который вы хотите проанализировать:
    • Для ветви извлеките заголовок ветви, которую необходимо проанализировать.
    • Для pull request перейдите к последнему коммиту pull request или сделанному GitHub коммиту слияния pull request.
  2. Настройте среду для базы кода, убедившись, что все зависимости доступны.
  3. Найдите команду сборки (если таковая имеется) для базы кода. Обычно она доступна в файле конфигурации в системе CI.
  4. Запустите codeql database create из корня контрольной копии вашего репозитория и соберите кодовую базу.
    • Чтобы создать одну базу данных CodeQL для одного поддерживаемого языка, используйте следующую команду:

      codeql database create <database> --command <build> --language=<language-identifier>
      
    • Чтобы создать одну базу данных CodeQL на язык для нескольких поддерживаемых языков, используйте следующую команду:

      codeql database create <database> --command <build> \
        --db-cluster --language=<language-identifier>,<language-identifier>
      

Примечание.

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

Полный список параметров для database create команды показан в следующей таблице:

Вариант Требуемое использование
<database> Укажите имя и расположение каталога, который будет создан для базы данных CodeQL. Команда завершится ошибкой, если вы попытаетесь перезаписать существующий каталог. Если также указать --db-cluster, это является родительским каталогом, и для каждого анализируемого языка создается подкаталог.
--language Укажите идентификатор языка для создания базы данных для одного из cpp, , csharp, go, java, javascriptpythonи ruby (используйте JavaScript для анализа кода TypeScript). При использовании с --db-cluster параметр принимает список с разделителями-запятыми или может быть указан более одного раза.
--command Рекомендуется. Используйте для указания команды сборки или скрипта, вызывающего процесс сборки для базы кода. Команды выполняются из текущей папки или из --source-root, если она указана. Не требуется для анализа Python и JavaScript/TypeScript.
--db-cluster Необязательно. Используйте в многоязычных кодовых базах для создания отдельной базы данных для каждого заданного языка --language.
--no-run-unnecessary-builds Рекомендуется. Используется для подавления команды сборки для языков, где интерфейс командной строки CodeQL не должен отслеживать сборку (например, Python и JavaScript/TypeScript).
--source-root Необязательно. Используйте, если вы запускаете CLI вне корневой директории репозитория. По умолчанию команда создания базы данных предполагает, что текущий каталог является корневым каталогом для исходных файлов; используйте этот параметр, чтобы указать другое расположение.

Пример использования одного языка

Этот пример создает базу данных CodeQL для репозитория, который был получен в /checkouts/example-repo. Он использует средство извлечения JavaScript для создания иерархического представления кода JavaScript и TypeScript в репозитории. Результирующая база данных хранится в /codeql-dbs/example-repo.

$ codeql database create /codeql-dbs/example-repo --language=javascript \
    --source-root /checkouts/example-repo

> Initializing database at /codeql-dbs/example-repo.
> Running command [/codeql-home/codeql/javascript/tools/autobuild.cmd]
    in /checkouts/example-repo.
> [build-stdout] Single-threaded extraction.
> [build-stdout] Extracting
...
> Finalizing database at /codeql-dbs/example-repo.
> Successfully created database at /codeql-dbs/example-repo.

Пример для нескольких языков

В этом примере создаются две базы данных CodeQL для репозитория, извлеченного в /checkouts/example-repo-multi. Он использует следующую информацию:

  • --db-cluster для запроса анализа на более чем одном языке.
  • --language для указания, для каких языков следует создавать базы данных.
  • --command, чтобы сообщить инструменту команду сборки для базы кода, здесь make.
  • --no-run-unnecessary-builds Чтобы сообщить инструменту пропустить команду сборки для языков, где она не нужна (например, для Python).

Результирующие базы данных хранятся в подкаталогах python и cpp в /codeql-dbs/example-repo-multi.

$ codeql database create /codeql-dbs/example-repo-multi \
    --db-cluster --language python,cpp \
    --command make --no-run-unnecessary-builds \
    --source-root /checkouts/example-repo-multi
Initializing databases at /codeql-dbs/example-repo-multi.
Running build command: [make]
[build-stdout] Calling python3 /codeql-bundle/codeql/python/tools/get_venv_lib.py
[build-stdout] Calling python3 -S /codeql-bundle/codeql/python/tools/python_tracer.py -v -z all -c /codeql-dbs/example-repo-multi/python/working/trap_cache -p ERROR: 'pip' not installed.
[build-stdout] /usr/local/lib/python3.6/dist-packages -R /checkouts/example-repo-multi
[build-stdout] [INFO] Python version 3.6.9
[build-stdout] [INFO] Python extractor version 5.16
[build-stdout] [INFO] [2] Extracted file /checkouts/example-repo-multi/hello.py in 5ms
[build-stdout] [INFO] Processed 1 modules in 0.15s
[build-stdout] <output from calling 'make' to build the C/C++ code>
Finalizing databases at /codeql-dbs/example-repo-multi.
Successfully created databases at /codeql-dbs/example-repo-multi.
$

Анализ базы данных CodeQL

После создания базы данных CodeQL выполните следующие действия, чтобы проанализировать ее:

  1. При необходимости запустите codeql pack download <packs>, чтобы загрузить любые пакеты CodeQL (бета-версии), которые нужно запустить во время анализа.
  2. Запустите codeql database analyze базу данных и укажите, какие пакеты и/или запросы следует использовать.
codeql database analyze <database> --format=<format> \
    --output=<output>  <packs,queries>

Примечание.

При анализе нескольких баз данных CodeQL для одного коммита вы должны указать категорию SARIF для каждого набора результатов, создаваемых этой командой. При отправке результатов на GitHub в ходе проверки кода эта категория используется для хранения результатов отдельно для каждого языка. Если вы забыли это сделать, то при каждой отправке будут перезаписаны предыдущие результаты.

codeql database analyze <database> --format=<format> \
    --sarif-category=<language-specifier> --output=<output> \
    <packs,queries>

Полный список параметров для database analyze команды показан в следующей таблице:

Вариант Требуемое использование
<database> Укажите путь к каталогу, содержащему анализируемую базу данных CodeQL.
<packs,queries> Укажите пакеты CodeQL или запросы для выполнения. Чтобы выполнить стандартные запросы, используемые для сканирования кода, опустите этот параметр. Другие наборы запросов, включенные в пакет CLI CodeQL, можно найти в /<extraction-root>/codeql/qlpacks/codeql-<language>/codeql-suites. Для получения информации о создании собственного набора запросов см. раздел «Создание наборов запросов CodeQL»[5] в документации по CLI CodeQL.
--format Укажите формат для файла результатов, созданного командой. Для отправки в GitHub это должно быть: sarif-latest
--output Укажите, где следует сохранить файл результатов SARIF.
--sarif-category Необязательно для анализа отдельных баз данных. Требуется определить язык при анализе нескольких баз данных для одного коммита в репозитории. Укажите категорию для включения в файл результатов SARIF для этого анализа. Категория используется для того, чтобы различать несколько анализов для одного и того же инструмента и коммита, но выполненных на разных языках или различных частях кода.
--sarif-add-query-help Необязательно. Используйте, если хотите включить доступную справку по запросам на языке разметки markdown для пользовательских запросов, используемых при анализе. Любая справка по пользовательским запросам, содержащимся в выходных данных SARIF, будет отображаться в пользовательском интерфейсе сканирования кода, если соответствующий запрос вызывает оповещение.
<packs> Необязательно. Используйте, если вы скачали пакеты запросов CodeQL и хотите выполнить запросы по умолчанию или наборы запросов, указанные в пакетах.
--threads Необязательно. Используйте, если требуется использовать более одного потока для выполнения запросов. Значение по умолчанию равно 1. Можно указать больше потоков для ускорения выполнения запросов. Чтобы задать число потоков, равное числу логических процессоров, укажите значение 0.
--verbose Необязательно. Используйте для получения более подробных сведений о процессе анализа и диагностических данных из процесса создания базы данных.

Простой пример

В этом примере анализируется база данных CodeQL, сохраненная в /codeql-dbs/example-repo, а результаты сохраняются в виде файла SARIF: /temp/example-repo-js.sarif. Он использует --sarif-category, чтобы включить в файл SARIF дополнительные сведения, идентифицирующие результаты как JavaScript. Это важно, когда необходимо проанализировать несколько баз данных CodeQL для одного коммита в репозитории.

$ codeql database analyze /codeql-dbs/example-repo  \
    javascript-code-scanning.qls --sarif-category=javascript
    --format=sarif-latest --output=/temp/example-repo-js.sarif

> Running queries.
> Compiling query plan for /codeql-home/codeql/qlpacks/
    codeql-javascript/AngularJS/DisablingSce.ql.
...
> Shutting down query evaluator.
> Interpreting results.

Отправка результатов на GitHub

Загрузка SARIF поддерживает не более 25 000 результатов за раз. Однако отображаются только первые 5000 результатов, приоритет которых определяется серьезностью. Если средство создает слишком много результатов, следует обновить конфигурацию и сосредоточиться на результатах для наиболее важных правил или запросов.

Максимальный размер файла SARIF в архиве GZIP, поддерживаемый для каждой передачи, составляет 10 МБ. Любые отправки свыше этого ограничения будут отклонены. Если файл SARIF слишком большой, так как он содержит слишком много результатов, необходимо обновить конфигурацию, чтобы сосредоточиться на результатах для наиболее важных правил или запросов. Дополнительные сведения об ограничениях и проверке ФАЙЛОВ SARIF см. в документации[6].

Перед отправкой результатов на GitHub необходимо определить оптимальный способ передачи приложения GitHub или личного маркера доступа, созданного ранее, в CodeQL CLI. Мы рекомендуем вам ознакомиться с руководством вашей системы CI по безопасному использованию хранилища секретов. CodeQL CLI поддерживает:

  • Взаимодействие с секретным хранилищем с помощью параметра --github-auth-stdin. Это рекомендуемый способ проверки подлинности.
  • Сохранение секрета в переменной среды GITHUB_TOKEN и запуск интерфейса командной строки без включения параметра --github-auth-stdin.
  • Передайте параметр командной строки --github-auth-stdin и укажите временный токен через стандартные входные данные. Это рекомендуется для тестирования.

Если вы решили использовать наиболее безопасный и надежный метод для вашего сервера CI, запустите codeql github upload-results на каждом файле результатов SARIF и включите --github-auth-stdin, если маркер не доступен в переменной среды GITHUB_TOKEN.

# GitHub App or personal access token available from a secret store
<call-to-retrieve-secret> | codeql github upload-results \
    --repository=<repository-name> \
    --ref=<ref> --commit=<commit> \
    --sarif=<file> --github-auth-stdin

# GitHub App or personal access token available in GITHUB_TOKEN
codeql github upload-results \
    --repository=<repository-name> \
    --ref=<ref> --commit=<commit> \
    --sarif=<file> 

Полный список параметров для github upload-results команды показан в таблице следующим образом.

Вариант Требуемое использование
--repository Укажите имя владельца репозитория, в который необходимо отправить данные. Владелец должен быть организацией в организации, имеющей лицензию на GitHub Advanced Security, и GitHub Advanced Security должна быть включена для репозитория, если репозиторий не является общедоступным.
--ref Укажите название ссылки, которую вы извлекли и проанализировали, чтобы результаты можно было соотнести с правильным кодом. Для ветви используйте refs/heads/BRANCH-NAME; для главного коммита запроса на слияние используйте refs/pulls/NUMBER/head; или для коммита слияния, созданного GitHub, для запроса на слияние, используйте refs/pulls/NUMBER/merge.
--commit Укажите полный SHA проанализированного коммита.
--sarif Укажите файл SARIF для загрузки.
--github-auth-stdin Необязательно. Используйте CLI для передачи GitHub App или личного маркера доступа, созданного для аутентификации с помощью REST API GitHub, через стандартный ввод. Это не требуется, если команда имеет доступ к переменной GITHUB_TOKEN среды с этим токеном.