Примечание: Эта статья была перенесена с веб-сайта документации По CodeQL в январе 2023 г.
Сведения о создании наборов запросов CodeQL
Наборы запросов CodeQL предоставляют способ выбора запросов на основе их имени файла, расположения на диске или в пакете CodeQL или свойствах метаданных. Создайте наборы запросов для запросов, которые вы хотите часто использовать в анализе CodeQL.
Наборы запросов позволяют передавать несколько запросов в CodeQL без необходимости указывать путь к каждому файлу запроса по отдельности. Определения набора запросов хранятся в файлах YAML с расширением .qls. Определение набора — это последовательность инструкций, в которой каждая инструкция является сопоставлением YAML с (как правило) одним ключом. Инструкции выполняются в том порядке, в котором они отображаются в определении набора запросов. У результате выполнения всех инструкций в определении набора будет создан набор выбранных запросов.
Примечание: Все пользовательские запросы, которые вы хотите добавить в набор запросов, должны находиться в пакете CodeQL и содержать правильные метаданные запроса. Дополнительные сведения см. в разделе Использование пользовательских запросов с CodeQL CLI.
Поиск запросов для добавления в набор запросов
При создании набора запросов сначала необходимо указать расположения запросов, которые требуется выбрать. Расположение одного или нескольких запросов можно определить с помощью:
-
Инструкция
queryуказывает CodeQL на поиск одного или нескольких указанных.qlфайлов:- query: <path-to-query>Аргумент должен быть одним или несколькими путями к файлам относительно пакета CodeQL, содержащего определение набора.
-
Инструкция
queriesуказывает CodeQL рекурсивно сканировать каталог на наличие.qlфайлов:- queries: <path-to-subdirectory>Путь к каталогу должен быть относительно корня пакета CodeQL, содержащего файл определения набора. Чтобы найти запросы относительно другого пакета CodeQL, добавьте
fromполе:- queries: <path-to-subdirectory> from: <ql-pack-name> version: ^x.y.zПоле
versionявляется необязательным и указывает диапазон совместимых версий этого пакета CodeQL. Если не указать версию, используется последняя версия пакета. -
Инструкция
qlpackуказывает CodeQL на разрешение запросов в наборе по умолчанию именованного пакета CodeQL:- qlpack: <qlpack-name> version: ^x.y.zПакет запросов по умолчанию включает рекомендуемый набор запросов внутри этого пакета запросов. Не все пакеты запросов имеют набор по умолчанию. Если заданный пакет запросов не определяет набор по умолчанию, инструкция qlpack будет разрешаться во все запросы в пакете.
Поле
versionявляется необязательным и указывает диапазон совместимых версий этого пакета CodeQL. Если не указать версию, используется последняя версия пакета.
Примечание: Если имена путей отображаются в определениях наборов запросов, они всегда должны быть предоставлены с косой чертой в /качестве разделителя каталогов. Это гарантирует, что определения набора запросов будут работать во всех операционных системах.
В определение набора необходимо добавить хотя бы одну queryинструкцию , queriesили qlpack , в противном случае запросы не будут выбраны. Если набор не содержит дальнейших инструкций, выбираются все запросы, найденные из списка файлов, в указанном каталоге или в именованном пакете CodeQL. При наличии дополнительных инструкций фильтрации будут выбраны только те запросы, которые соответствуют ограничениям, налагаемым этими инструкциями.
Фильтрация запросов в наборе запросов
Определив начальный набор запросов для добавления в набор, указав инструкции query, queriesили qlpack , можно добавить include инструкции и exclude . Эти инструкции определяют критерии выбора на основе определенных свойств:
- При выполнении
includeинструкции по набору запросов все запросы, соответствующие вашим условиям, сохраняются в выделенном фрагменте, а запросы, которые не соответствуют, удаляются. - При выполнении инструкций
excludeпо набору запросов все запросы, соответствующие вашим условиям, удаляются из выбора, а запросы, которые не соответствуют, сохраняются.
Порядок инструкций фильтра имеет важное значение. Первая инструкция фильтра, которая отображается после инструкций по поиску, определяет, включены ли запросы или исключены по умолчанию. Если первым фильтром includeявляется , изначально расположенные запросы будут частью набора только в том случае, если они соответствуют явному include фильтру. Если первым фильтром excludeявляется , изначально расположенные запросы являются частью набора, если они не исключены явным образом.
Последующие инструкции выполняются по порядку, а инструкции, которые отображаются позже в файле, имеют приоритет над предыдущими инструкциями. Таким образом, include инструкции могут быть переопределены более поздними exclude инструкциями, которые соответствуют тому же запросу. Аналогичным образом , excludes могут быть переопределены более поздним include.
Для обеих инструкций аргумент является блоком ограничений, то есть схемой YAML, представляющей ограничения. Каждое ограничение — это запись карты, где ключ обычно является свойством метаданных запроса. Значение может быть следующим:
- Одна строка.
- Регулярное
/выражение, включаемое в себя. - Список, содержащий строки, регулярные выражения или и то, и другое.
Чтобы сопоставить ограничение, значение метаданных должно соответствовать одной из строк или регулярных выражений. При наличии нескольких ключей метаданных каждый ключ должен быть сопоставлен.
Стандартные ключи метаданных, доступные для сопоставления: description, id, , kind, tags``name, precisionи problem.severity.
Дополнительные сведения о свойствах метаданных запроса см. в разделе Метаданные для запросов CodeQL.
Помимо тегов метаданных, ключи в блоке ограничений также могут быть следующими:
query filename— соответствует компоненту последнего пути имени файла запроса.query path— соответствует пути к файлу запроса относительно его включающего в себя пакет CodeQL.tags contain— одна из заданных строк соответствия должна соответствовать одному из разделенных пробелами компонентов значения@tagsсвойства метаданных.tags contain all— каждая из заданных строк соответствия должна соответствовать одному из компонентов@tagsсвойства метаданных.
Примеры фильтрации выполняемых запросов
Распространенным вариантом использования является создание набора запросов, который выполняет все запросы в пакете CodeQL, за исключением нескольких конкретных запросов, которые пользователь не хочет выполнять. Как правило, рекомендуется выполнять фильтрацию по запросу id, который является уникальным и стабильным идентификатором для каждого запроса. Следующие три определения набора запросов семантически идентичны и фильтруются по запросу id:
Этот фильтр соответствует всем запросам в наборе codeql/cpp-queriesпо умолчанию , за исключением двух запросов с исключенными идентификаторами:
- qlpack: codeql/cpp-queries
- exclude:
id:
- cpp/cleartext-transmission
- cpp/cleartext-storage-file
В этом примере для каждого запроса используется отдельная exclude инструкция:
- qlpack: codeql/cpp-queries
- exclude:
id: cpp/cleartext-transmission
- exclude:
id: cpp/cleartext-storage-file
В этом примере регулярное выражение исключает те же два запроса. Он также исключит все будущие запросы, добавленные в набор с идентификаторами, которые начинаются: cpp/cleartext-:
- qlpack: codeql/cpp-queries
- exclude:
id:
- /^cpp\/cleartext-.*/
Чтобы определить набор, который выбирает все запросы в наборе codeql/cpp-queries по умолчанию пакета CodeQL, а затем уточняет их, чтобы включить только запросы безопасности, используйте следующую команду:
- qlpack: codeql/cpp-queries
- include:
tags contain: security
Чтобы определить набор, который выбирает все запросы с @kind problem каталогом и @precision high из каталога my-custom-queries , используйте следующую команду:
- queries: my-custom-queries
- include:
kind: problem
precision: very-high
Обратите внимание, что следующее определение набора запросов ведет себя иначе, чем в приведенном выше определении. Это определение выбирает запросы, которые являются @kind problem или являются @precision very-high:
- queries: my-custom-queries
- include:
kind: problem
- include:
precision: very-high
Чтобы создать набор, который выбирает из каталога все запросы с @kind problem my-custom-queries , кроме запросов с @problem.severity recommendation, используйте следующую команду:
- queries: my-custom-queries
- include:
kind: problem
- exclude:
problem.severity: recommendation
Чтобы создать набор, который выбирает все запросы с @tag security и @problem.severity high или very-high из codeql/cpp-queries пакета CodeQL, используйте следующую команду:
- queries: .
from: codeql/cpp-queries
- include:
tags contain: security
problem.severity:
- high
- very-high
Примечание: Вы можете использовать команду , codeql resolve queries /path/to/suite.qls чтобы узнать, какие запросы выбраны определением набора запросов. Дополнительные сведения см. в справочной документации по устранению запросов .
Повторное использовать существующие определения набора запросов
Существующие определения наборов запросов можно использовать повторно, указав:
-
Инструкция
importдобавляет запросы, выбранные ранее определенным.qlsфайлом, в текущий набор:- import: <path-to-query-suite>Путь к импортированному набору должен быть относительно пакета CodeQL, содержащего текущее определение набора. Если импортированный набор запросов находится в другом пакете QL, можно использовать следующее:
- import: <path-to-query-suite> from: <ql-pack> version: ^x.y.zПоле
versionявляется необязательным и указывает диапазон совместимых версий этого пакета CodeQL. Если не указать версию, используется последняя версия пакета.Запросы, добавленные с помощью инструкции,
importможно фильтровать с помощью последующихexcludeинструкций. -
Инструкция
apply— добавляет все инструкции из ранее определенного.qlsфайла в текущий набор. Инструкции в примененном.qlsфайле выполняются так, как если бы они отображались вместоapply. Всеincludeинструкции иexcludeиз примененного набора также действуют с запросами, добавленными в предыдущие инструкции:- apply: <path-to-query-suite>Инструкцию
applyтакже можно использовать для применения набора многократно используемых условий, сохраненных в.ymlфайле, к нескольким определениям запросов. Дополнительные сведения см. в примерах ниже.
Примеры повторного использования
Чтобы использовать одни и те же условия в нескольких определениях наборов запросов, создайте отдельный .yml файл, содержащий инструкции. Например, сохраните следующий код в файле с именем reusable-instructions.yml:
- include:
kind:
- problem
- path-problem
tags contain: security
precision:
- high
- very-high
Добавьте reusable-instructions.yml в тот же пакет CodeQL, что и текущий набор запросов. Затем в одном или нескольких наборах запросов используйте инструкцию apply для применения повторно используемых инструкций к текущему набору. Например:
- queries: queries/cpp/custom
- apply: reusable-instructions.yml
При этом запросы будут отфильтрованы, queries/cpp/custom включив только те, которые соответствуют многократно используемым условиям.
Вы также можете создать определение набора с помощью reusable-instructions.yml запросов в другом пакете CodeQL. .qls Если файл находится в том же пакете CodeQL, что и запросы, вы можете добавить from поле сразу после инструкции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
Распространенный вариант использования инструкции import — применение дополнительного фильтра к запросам из другого набора запросов. Например, этот набор будет дополнительно фильтровать cpp-security-and-quality набор и исключать low запросы точности и medium :
- import: codeql-suites/cpp-security-and-quality.qls
from: codeql/cpp-queries
- exclude:
precision:
- low
- medium
Если вы хотите, чтобы include запросы импортировались из другого набора, синтаксис немного отличается:
- import: codeql-suites/cpp-security-and-quality.qls
from: codeql/cpp-queries
- exclude: {}
- include:
precision:
- very-high
- high
Обратите внимание на пустую exclude инструкцию. Это необходимо для того, чтобы последующие include инструкции могли фильтровать запросы из импортированного набора.
Именование набора запросов
Вы можете указать имя для набора запросов, указав инструкцию description :
- description: <name-of-query-suite>
Это значение отображается при выполнении запросов разрешения codeql, если набор добавляется в "хорошо известный" каталог. Дополнительные сведения см. в разделе Указание хорошо известных наборов запросов.
Сохранение набора запросов
Сохраните набор запросов в файле с расширением .qls и добавьте его в пакет CodeQL. Дополнительные сведения см. в разделе Сведения о пакетах CodeQL.
Указание хорошо известных наборов запросов
Пакеты CodeQL можно использовать для объявления каталогов, содержащих "хорошо известные" наборы запросов. Вы можете использовать "хорошо известные" наборы запросов в командной строке, ссылаясь на их имя файла без указания полного пути. Это позволяет просто указать набор запросов, не выполняя поиск в пакетах и дистрибутивах CodeQL.
Чтобы объявить каталог, содержащий "хорошо известные" наборы запросов, добавьте каталог suites в свойство в файле в qlpack.yml корне пакета CodeQL.
Дополнительные сведения см. в разделе Сведения о пакетах CodeQL.
Использование наборов запросов с CodeQL
Вы можете указать наборы запросов в командной строке для любой команды, принимающей .qls файлы. Например, можно компилировать запросы, выбранные определением набора, с помощью query compileили использовать запросы в анализе с помощью database analyze. Дополнительные сведения об анализе баз данных CodeQL см. в разделе Анализ баз данных с помощью CodeQL CLI.