Acerca de la creación de conjuntos de consultas de CodeQL
Nota: En este artículo se describen las características disponibles con el paquete CodeQL CLI 2.18.4 que se incluye en la versión inicial de GitHub Enterprise Server 3.15.
Si el administrador del sitio ha actualizado tu versión de la CodeQL CLI a una versión más reciente, consulta la versión de GitHub Enterprise Cloud de este artículo para obtener información sobre las características más recientes.
Los conjuntos de consultas de CodeQL proporcionan una manera de seleccionar consultas, según su nombre de archivo, ubicación en el disco o en un paquete de CodeQL o propiedades de metadatos. Crea conjuntos de consultas para consultas que quieras usar con frecuencia en los análisis de CodeQL.
Los conjuntos de consultas permiten pasar varias consultas a CodeQL sin tener que especificar la ruta de acceso en cada archivo de consulta individualmente. Las definiciones del conjunto de consultas se almacenan en archivos YAML con la extensión .qls
. Una definición de conjuntos es una secuencia de instrucciones, donde cada instrucción es una asignación de YAML que (normalmente) tiene una sola clave. Las instrucciones se ejecutan en el orden en que aparecen en la definición del conjunto de consultas. Una vez ejecutadas todas las instrucciones de la definición del conjunto, el resultado es un conjunto de consultas seleccionadas.
Note
Las consultas personalizadas que quieras agregar a un conjunto de consultas deben estar en un paquete de "CodeQL" y contener los metadatos de consulta correctos. Para obtener más información, consulta "Uso de consultas personalizadas con la CodeQL CLI".
Búsqueda de consultas que se van a agregar a un conjunto de consultas
Al crear un conjunto de consultas, primero debes especificar las ubicaciones de las consultas que quieres seleccionar. Puedes definir la ubicación de una o varias consultas mediante lo siguiente:
-
Una instrucción
query
: indica a CodeQL que busque uno o varios archivos.ql
especificados:- query: <path-to-query>
El argumento debe ser una o varias rutas de acceso de archivo, que hagan referencia al paquete de CodeQL que contiene la definición del conjunto.
-
Una instrucción
queries
: indica a CodeQL que examine de forma recursiva un directorio para los archivos.ql
:- queries: <path-to-subdirectory>
La ruta de acceso del directorio debe hacer referencia a la raíz del paquete de CodeQL que contiene el archivo de definición del conjunto. Para buscar las consultas que hacen referencia a un paquete de CodeQL, agrega un campo
from
:- queries: <path-to-subdirectory> from: <ql-pack-name> version: ^x.y.z
El campo
version
es opcional y especifica un intervalo de versiones compatibles de este paquete de CodeQL. Si no especificas una versión del paquete, se usará la más reciente. -
Una instrucción
qlpack
: indica a CodeQL que resuelva las consultas en el conjunto predeterminado del paquete de CodeQL nombrado:- qlpack: <qlpack-name> version: ^x.y.z
El conjunto predeterminado de un paquete de consultas incluye un conjunto recomendado de consultas dentro de ese paquete de consultas. No todos los paquetes de consultas tienen un conjunto predeterminado. Si el paquete de consultas dado no define un conjunto predeterminado, la instrucción qlpack se resolverá en todas las consultas del paquete.
El campo
version
es opcional y especifica un intervalo de versiones compatibles de este paquete de CodeQL. Si no especificas una versión del paquete, se usará la más reciente.
Note
Cuando los nombres de rutas de acceso aparecen en las definiciones del conjunto de consultas, siempre deben llevar una barra diagonal, /
, como separador de directorios. Esto garantiza que las definiciones del conjunto de consultas funcionen en todos los sistemas operativos.
Debes agregar al menos una instrucción query
, queries
o qlpack
a la definición del conjunto; de lo contrario, no se seleccionará ninguna consulta. Si el conjunto no contiene más instrucciones, se seleccionan todas las consultas que se encuentran en la lista de archivos, en el directorio especificado o en el paquete de CodeQL nombrado. Si hay instrucciones de filtrado adicionales, solo se seleccionarán las consultas que coincidan con las restricciones que han impuesto esas instrucciones.
Filtrado de las consultas en un conjunto de consultas
Después de definir el conjunto inicial de consultas que se van a agregar al conjunto especificando instrucciones query
, queries
o qlpack
, puedes agregar instrucciones include
y exclude
. Estas instrucciones definen criterios de selección en función de propiedades específicas:
- Al ejecutar una instrucción
include
en un conjunto de consultas, las consultas que coincidan con las condiciones se conservan en la selección y las que no coincidan se quitan. - Al ejecutar una instrucción
exclude
en un conjunto de consultas, las consultas que coincidan con las condiciones se quitan de la selección y las que no coincidan se conservan.
El orden de las instrucciones de filtro es importante. La primera instrucción de filtro que aparece después de las instrucciones de ubicación determina si las consultas se incluyen o excluyen de manera predeterminada. Si el primer filtro es un elemento include
, las consultas ubicadas al principio solo formarán parte del conjunto si coinciden con un filtro explícito include
. Si el primer filtro es un elemento exclude
, las consultas ubicadas al principio forman parte del conjunto a menos que se excluyan de forma explícita.
Las instrucciones posteriores se ejecutan en orden y las instrucciones que aparecen más adelante en el archivo tienen prioridad sobre las instrucciones anteriores. Por lo tanto, las instrucciones include
se pueden invalidar mediante instrucciones exclude
posteriores que coincidan con la misma consulta. Del mismo modo, un elemento include
posterior puede invalidar elementos exclude
.
Para ambas instrucciones, el argumento es un bloque de restricciones, es decir, una asignación de YAML que representa las restricciones. Cada restricción es una entrada de la asignación, donde la clave suele ser una propiedad de metadatos de consulta. El valor puede ser lo siguiente:
- Una sola cadena.
- Una expresión regular incluida entre
/
. - Una lista que contiene cadenas, expresiones regulares o ambas.
Para que coincida con una restricción, un valor de metadatos debe coincidir con una de las cadenas o expresiones regulares. Cuando hay más de una clave de metadatos, deben coincidir todas las claves.
Las claves de metadatos estándar disponibles para establecer coincidencias son: description
, id
, kind
, name
, tags
, precision
y problem.severity
.
Para obtener más información sobre las propiedades de metadatos de consulta, consulta "Metadatos para las consultas de CodeQL".
Además de las etiquetas de metadatos, las claves del bloque de restricciones también pueden ser lo siguiente:
query filename
: coincide con el último componente de ruta de acceso del nombre de archivo de la consulta.query path
: coincide con la ruta de acceso al archivo de la consulta que hace referencia a su paquete de datos de CodeQL incluido.tags contain
: una de las cadenas de coincidencia especificadas debe coincidir con uno de los componentes separados por espacios del valor de la propiedad de metadatos@tags
.tags contain all
: cada una de las cadenas de coincidencia especificadas debe coincidir con uno de los componentes de la propiedad de metadatos@tags
.
Ejemplos de filtrado de las consultas que se van a ejecutan
Un caso de uso común es crear un conjunto de consultas que ejecute todas las consultas de un paquete de CodeQL, excepto algunas consultas específicas que el usuario no quiere ejecutar. Por lo general, se recomienda filtrar por la consulta id
, que es un identificador único y estable para cada consulta. Las tres definiciones de conjunto de consultas siguientes son semánticamente idénticas y filtran por la consulta id
:
Este filtro coincide con todas las consultas del conjunto predeterminado de codeql/cpp-queries
, excepto para las dos consultas con los identificadores excluidos:
- qlpack: codeql/cpp-queries
- exclude:
id:
- cpp/cleartext-transmission
- cpp/cleartext-storage-file
En este ejemplo, se usa una instrucción exclude
independiente para cada consulta:
- qlpack: codeql/cpp-queries
- exclude:
id: cpp/cleartext-transmission
- exclude:
id: cpp/cleartext-storage-file
En este ejemplo, una expresión regular excluye las mismas dos consultas. También excluiría las consultas futuras agregadas al conjunto con identificadores que comienzan por cpp/cleartext-
:
- qlpack: codeql/cpp-queries
- exclude:
id:
- /^cpp\/cleartext-.*/
Para definir un conjunto que seleccione todas las consultas del conjunto predeterminado del paquete codeql/cpp-queries
de CodeQL y, después, las mejore para incluir solo consultas de seguridad, usa lo siguiente:
- qlpack: codeql/cpp-queries
- include:
tags contain: security
Para definir un conjunto que seleccione todas las consultas con @kind problem
y @precision high
desde el directorio my-custom-queries
, usa lo siguiente:
- queries: my-custom-queries
- include:
kind: problem
precision: very-high
Tenga en cuenta que la definición siguiente del conjunto de consultas se comporta de forma diferente de la definición anterior. Esta definición selecciona las consultas que son @kind problem
o @precision very-high
:
- queries: my-custom-queries
- include:
kind: problem
- include:
precision: very-high
Para crear un conjunto que seleccione todas las consultas con @kind problem
desde el directorio my-custom-queries
, excepto aquellas que incluyan @problem.severity recommendation
, usa lo siguiente:
- queries: my-custom-queries
- include:
kind: problem
- exclude:
problem.severity: recommendation
Para crear un conjunto que seleccione todas las consultas con @tag security
y @precision high
, o very-high
, desde el paquete codeql/cpp-queries
de CodeQL, usa lo siguiente:
- queries: .
from: codeql/cpp-queries
- include:
tags contain: security
precision:
- high
- very-high
Note
Puedes usar el comando codeql resolve queries /path/to/suite.qls
para ver qué consultas ha seleccionado una definición de conjunto de consultas. Para obtener más información, vea «resolve queries».
Reutilización de definiciones del conjunto de consultas existente
Las definiciones del conjunto de consultas existente se pueden reutilizar especificando lo siguiente:
-
Una instrucción
import
: agrega las consultas que ha seleccionado previamente un archivo.qls
definido al conjunto actual:- import: <path-to-query-suite>
La ruta de acceso al conjunto importado debe hacer referencia al paquete de CodeQL que contiene la definición del conjunto actual. Si el conjunto de consultas importado está en otro paquete de QL, puedes usar lo siguiente:
- import: <path-to-query-suite> from: <ql-pack> version: ^x.y.z
El campo
version
es opcional y especifica un intervalo de versiones compatibles de este paquete de CodeQL. Si no especificas una versión del paquete, se usará la más reciente.Las consultas agregadas mediante una instrucción
import
se pueden filtrar mediante instruccionesexclude
posteriores. -
Una instrucción
apply
: agrega todas las instrucciones de un archivo.qls
definido previamente al conjunto actual. Las instrucciones del archivo.qls
aplicado se ejecutan como si aparecieran en lugar deapply
. Las instruccionesinclude
yexclude
del conjunto aplicado también actúan en las consultas que han agregado instrucciones anteriores:- apply: <path-to-query-suite>
La instrucción
apply
también se puede usar para aplicar un conjunto de condiciones reutilizables, guardadas en un archivo.yml
, en varias definiciones de consulta. Para obtener más información, consulta los ejemplos que se indican a continuación.
Ejemplos de reutilización
Para usar las mismas condiciones en varias definiciones del conjunto de consultas, crea un archivo .yml
independiente que incluya las instrucciones. Por ejemplo, guarda lo siguiente en un archivo denominado reusable-instructions.yml
:
- include:
kind:
- problem
- path-problem
tags contain: security
precision:
- high
- very-high
Agrega reusable-instructions.yml
en el mismo paquete de CodeQL que el conjunto de consultas actual. Después, en uno o varios conjuntos de consultas, usa la instrucción apply
para aplicar las instrucciones reutilizables en el conjunto de consultas actual. Por ejemplo:
- queries: queries/cpp/custom
- apply: reusable-instructions.yml
Esto filtrará las consultas en queries/cpp/custom
para incluir solo las que coincidan con las condiciones reutilizables.
También puedes crear una definición de conjunto mediante reusable-instructions.yml
en consultas en un paquete de CodeQL distinto. Si el archivo .qls
está en el mismo paquete de CodeQL que las consultas, puedes agregar un campo from
inmediatamente después de la instrucción 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
Un caso de uso común para una instrucción import
es aplicar un filtro adicional a las consultas desde otro conjunto de consultas. Por ejemplo, este conjunto filtrará aún más el conjunto cpp-security-and-quality
y excluirá las consultas de precisión low
y medium
:
- import: codeql-suites/cpp-security-and-quality.qls
from: codeql/cpp-queries
- exclude:
precision:
- low
- medium
Si quieres que las consultas include
se importen desde otro conjunto, la sintaxis es un poco diferente:
- import: codeql-suites/cpp-security-and-quality.qls
from: codeql/cpp-queries
- exclude: {}
- include:
precision:
- very-high
- high
Observe la instrucción exclude
vacía. Esto es necesario para garantizar que la instrucción include
posterior pueda filtrar las consultas del conjunto importado.
Nomenclatura de un conjunto de consultas
Puedes proporcionar un nombre para el conjunto de consultas especificando una instrucción description
:
- description: <name-of-query-suite>
Almacenamiento de un conjunto de consultas
Guarda el conjunto de consultas en un archivo con una extensión .qls
y agrégalo a un paquete de CodeQL. Para obtener más información, vea «Personalización del análisis con paquetes de CodeQL».
Uso de conjuntos de consultas con CodeQL
Puedes especificar conjuntos de consultas en la línea de comandos para cualquier comando que acepte archivos .qls
. Por ejemplo, puedes compilar las consultas que ha seleccionado una definición de conjunto mediante query compile
o bien usar las consultas de un análisis mediante database analyze
. Para más información sobre cómo analizar bases de datos de CodeQL, consulta "Análisis del código con consultas de CodeQL".