Skip to main content

Создание наборов запросов CodeQL

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

Кто может использовать эту функцию?

CodeQL доступен для следующих типов репозитория:

Создание наборов запросов CodeQL

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

Наборы запросов позволяют передавать несколько запросов в CodeQL без необходимости указывать путь к каждому файлу запроса по отдельности. Определения набора запросов хранятся в файлах YAML с расширением .qls. Определение набора — это последовательность инструкций, в которой каждая инструкция является сопоставлением YAML с (как правило) одним ключом. Инструкции выполняются в том порядке, в котором они отображаются в определении набора запросов. У результате выполнения всех инструкций в определении набора будет создан набор выбранных запросов.

Note

Все пользовательские запросы, которые необходимо добавить в набор запросов, должны находиться в пакете 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 . Если вы не указываете версию, используется последняя версия пакета.

Note

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

Необходимо добавить по крайней мере одну query``queriesили qlpack инструкцию в определение набора, в противном случае запросы не будут выбраны. Если набор не содержит дальнейших инструкций, все запросы, найденные из списка файлов, в указанном каталоге или в именованном пакете CodeQL выбираются. Если существуют дополнительные инструкции по фильтрации, будут выбраны только запросы, соответствующие ограничениям, введенным этими инструкциями.

Фильтрация запросов в наборе запросов

После определения начального набора запросов, добавляемых в наборquery``queries``qlpack, можно добавить include и exclude инструкции. Эти инструкции определяют критерии выбора на основе определенных свойств:

  • При выполнении include инструкции по набору запросов все запросы, соответствующие вашим условиям, сохраняются в выборе, а запросы, которые не совпадают, удаляются.
  • При выполнении exclude инструкций по набору запросов все запросы, соответствующие вашим условиям, удаляются из выбора, а запросы, которые не соответствуют совпадению, сохраняются.

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

Последующие инструкции выполняются по порядку, а инструкции, которые отображаются позже в файле, имеют приоритет над предыдущими инструкциями. Таким образом, include инструкции можно переопределить более поздними exclude инструкциями, соответствующими тому же запросу. Аналогичным образом можно excludeпереопределить более поздние includeверсии.

Для обоих инструкций аргумент является блоком ограничений, т. е. картой YAML, представляющей ограничения. Каждое ограничение — это запись карты, где ключ обычно является свойством метаданных запроса. Значение может быть следующим:

  • Одна строка.
  • Закрытое регулярное /выражение.
  • Список, содержащий строки, регулярные выражения или оба.

Чтобы соответствовать ограничению, значение метаданных должно соответствовать одной из строк или регулярных выражений. Если существует несколько ключей метаданных, каждый ключ должен быть сопоставлен. Стандартные ключи метаданных, доступные для сопоставления: description, id, kind, , name, tags``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

Обратите внимание, что следующее определение набора запросов отличается от приведенного выше определения. Это определение выбирает запросы, которые являются или_ являются @precision very-high``@kind problem _:

- 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 @precision high very-high пакетом codeql/cpp-queries CodeQL, используйте следующую команду:

- queries: .
  from: codeql/cpp-queries
- include:
    tags contain: security
    precision:
    - high
    - very-high

Note

Чтобы узнать, какие запросы выбраны определением набора запросов, можно использовать 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. exclude Все include и инструкции из примененного набора также действуют над запросами, добавленными любыми предыдущими инструкциями:

    - 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>

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

Сохраните набор запросов в файле с .qls расширением и добавьте его в пакет CodeQL . Дополнительные сведения см. в разделе Настройка анализа с помощью пакетов CodeQL.

Использование наборов запросов с CodeQL

Наборы запросов можно указать в командной строке для любой команды, которая принимает .qls файлы. Например, можно скомпилировать запросы, выбранные определением набора, с помощью query compileили использовать запросы в анализе.database analyze Дополнительные сведения об анализе баз данных CodeQL см. в разделе Анализ кода с помощью запросов CodeQL.

Дополнительные материалы