Preparación de una base de datos para CodeQL

Completado

CodeQL trata el código como los datos. El análisis de CodeQL se basa en la extracción de datos relacionales del código y su uso para crear una base de datos CodeQL. Estas bases de datos contienen toda la información importante sobre un código base.

A continuación, puede ejecutar consultas codeQL en esta base de datos para identificar vulnerabilidades de seguridad, errores y otros errores. Puede escribir sus propias consultas o ejecutar consultas codeQL estándar escritas por investigadores de GitHub y colaboradores de la comunidad.

Puede usar la CLI de CodeQL independiente para crear y analizar una base de datos CodeQL. El análisis de la base de datos genera resultados en formato de intercambio de resultados de análisis estáticos (SARIF), que se puede cargar en un repositorio de GitHub para ver los detalles de la alerta.

Arquitectura de análisis de CodeQL

El análisis de CodeQL sigue una canalización que transforma el código fuente en datos consultables, ejecuta consultas de seguridad y publica los resultados como alertas de análisis de código.

El flujo de trabajo de escaneo es:

  1. Código fuente: CodeQL parte del contenido del repositorio correspondiente al commit que se está analizando.
  2. Extracción: Un extractor específico del lenguaje lee el código y recopila hechos sobre archivos de código fuente, sintaxis, flujo de control y flujo de datos.
  3. Creación de la base de datos: Los hechos extraídos se almacenan en una base de datos CodeQL. Cada base de datos representa un idioma en el código base.
  4. Ejecución de consultas: CodeQL ejecuta consultas mantenidas GitHub, consultas de la comunidad o consultas personalizadas en la base de datos.
  5. Generación de SARIF: Los resultados de la consulta se escriben en formato de intercambio de resultados de análisis estáticos (SARIF).
  6. GitHub análisis de código: los resultados de SARIF se cargan en GitHub y se muestran como alertas de examen de código.

Esta arquitectura separa la extracción de código de la ejecución de consultas. Una vez creada una base de datos, puede ejecutar diferentes conjuntos de consultas en la misma base de datos sin volver a extraer el código.

Estrategia de lenguaje

CodeQL admite lenguajes compilados e interpretados, pero la estrategia de extracción depende del tipo de lenguaje.

Lenguajes compilados

Para lenguajes compilados como:

  • C/C++
  • C#
  • Java
  • Kotlin
  • Óxido
  • Swift
  • Go

CodeQL a menudo necesita comprender cómo se compila el proyecto. Durante la creación de la base de datos, CodeQL puede supervisar el proceso de compilación para que pueda extraer los archivos de origen procesados por el compilador.

Para obtener los resultados más confiables, configure comandos de compilación explícitos en lugar de confiar en la compilación automática o en ninguna opción de compilación.

Idiomas interpretados

Para idiomas interpretados como:

  • Python
  • JavaScript/TypeScript
  • Ruby

CodeQL extrae información directamente desde el código fuente sin necesidad de un comando de compilación independiente.

Repositorios de varios lenguajes

Para repositorios que contienen varios idiomas admitidos:

  • Cree una base de datos independiente para cada idioma.
  • En Acciones de GitHub, use una matriz de lenguaje para que cada idioma se inicialice, extraiga y analice correctamente.

Preparación de la base de datos para CodeQL

Antes de generar una base de datos CodeQL:

  1. Instale y configure la CLI de CodeQL.
  2. Consulte la versión del código base que desea analizar.

Para los lenguajes compilados:

  • Asegúrate de que el proyecto esté listo para compilarse.
  • Instale todas las dependencias necesarias de antemano.
  • CodeQL extrae una representación relacional de cada archivo de origen para crear la base de datos.

Para idiomas interpretados:

  • El extractor se ejecuta directamente en el código fuente.
  • Las dependencias se resuelven automáticamente durante la extracción.

En el caso de los lenguajes compilados, CodeQL supervisa el proceso de compilación normal. Cada vez que el compilador procesa un archivo de origen, CodeQL crea una copia y extrae toda la información pertinente necesaria para el análisis.

Configuración de la CLI

Siga estos pasos para instalar la CLI de CodeQL.

1. Descargar el paquete de la CLI de CodeQL

El método de instalación recomendado está descargando el paquete agrupado, lo que garantiza la compatibilidad entre la CLI, las bibliotecas y los paquetes de consulta.

El paquete incluye:

  • La CLI de CodeQL
  • Consultas y bibliotecas de CodeQL compatibles
  • Paquetes de consultas precompilados

Para descargar el paquete:

  1. Vaya a la página Versiones del repositorio público CodeQL.
  2. Descargue el paquete específico de la plataforma en Recursos.

La página Versiones también incluye:

  • Notas de lanzamiento
  • Versiones anteriores
  • codeql-bundle.tar.gz, que admite todas las plataformas

2. Extraer el archivo

Extraiga el .zip archivo en un directorio de su elección.

Los usuarios de macOS Catalina (o posterior) deben completar pasos de configuración adicionales, tal como se describe en la documentación de la CLI de CodeQL.

3. Ejecutar CodeQL

Después de la extracción, cualquiera de las siguientes opciones:

  • ¡Corre!
<extraction-root>/codeql/codeql

o

  • Añadir:
<extraction-root>/codeql

a su sistema PATH para que pueda invocar la CLI simplemente así:

codeql

Ahora puede ejecutar comandos codeQL.

Comprobación de la configuración de la CLI

Ejecute los comandos siguientes para comprobar que la instalación funciona correctamente.

Mostrar paquetes de CodeQL instalados:

codeql resolve packs

Si el archivo ejecutable no está en PATH, use:

<extraction-root>/codeql/codeql resolve packs

Si faltan paquetes de idioma esperados, compruebe que descargó el paquete CodeQL, no la CLI independiente.

Mostrar los idiomas admitidos:

codeql resolve languages

Creación de base de datos

Cree una base de datos CodeQL a partir de la raíz del proyecto:

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

Reemplazar:

  • <database> con el directorio de destino.
  • <language-identifier> con el identificador de idioma que se va a analizar.

También puede usar las siguientes opciones:

Opción Purpose
--source-root Especifica el directorio raíz que contiene el código fuente.
--db-cluster Crea bases de datos para varios lenguajes.
--command Especifica el comando de compilación para los lenguajes compilados. No es necesario para Python, Ruby o JavaScript.
--no-run-unnecessary-builds Omite las compilaciones innecesarias cuando se usa con --db-cluster.

Después de la ejecución correcta:

  • Se crea un nuevo directorio de base de datos.
  • Cuando se usa --db-cluster, se crea un subdirectorio para cada idioma.

Cada base de datos contiene:

  • Datos de análisis relacional
  • Archivo de origen
  • Metadatos necesarios para el análisis de CodeQL

El archivo de origen es una instantánea de los archivos de origen en el momento en que se creó la base de datos y se usa al mostrar los resultados del análisis.

Consideraciones de generación y rendimiento de la base de datos

Después de crear una base de datos CodeQL, es importante comprender cómo funciona la generación de bases de datos y cómo afecta al rendimiento.

Métodos de generación de base de datos

Puede generar bases de datos codeQL mediante:

CLI de CodeQL

Cree bases de datos y ejecute el análisis manualmente.

Este enfoque es útil para:

  • Desarrollo local
  • Depuración
  • Configuraciones avanzadas

flujos de trabajo de Acciones de GitHub

La mayoría de las organizaciones automatizan la generación de bases de datos a través de Acciones de GitHub.

Un flujo de trabajo típico:

  1. Inicializa CodeQL.
  2. Crea bases de datos.
  3. Ejecuta consultas.
  4. Carga los resultados de SARIF en GitHub.

Bases de datos por idioma

CodeQL crea una base de datos independiente para cada idioma admitido.

Cada idioma:

  • Usa su propio extractor.
  • Usa su propio esquema de base de datos.
  • Se analiza de forma independiente.

En el caso de los repositorios multilingües, puede:

  • Use la --db-cluster opción con la CLI.
  • Configure una matriz de idioma en Acciones de GitHub.

Una matriz de lenguaje permite el análisis paralelo y la cobertura completa del idioma.

Extracción basada en compilación para lenguajes compilados

Para los lenguajes compilados:

  • CodeQL supervisa el proceso de compilación.
  • La compilación debe completarse correctamente.
  • El autobuild automático no funciona de forma confiable para cada proyecto.

Para obtener los mejores resultados, defina pasos de compilación explícitos antes del análisis.

Para los lenguajes interpretados, CodeQL extrae directamente del código fuente sin necesidad de una compilación.

Consideraciones sobre el rendimiento

El tiempo de creación y análisis de la base de datos depende de varios factores.

Tamaño del repositorio

Los repositorios más grandes requieren más tiempo de extracción y análisis.

Varios idiomas

Use una matriz de lenguaje para analizar los lenguajes en paralelo y reducir el tiempo de ejecución total.

Recursos de CI

El análisis de CodeQL puede consumir muchos recursos.

Aumentar la CPU o la memoria de los runners puede mejorar significativamente el rendimiento.

Ámbito de análisis

Puede reducir el tiempo de análisis limitando el código que se examina, por ejemplo, excluyendo:

  • Archivos de prueba
  • Código generado

En general, el tiempo de análisis es proporcional a la cantidad de código fuente que se está procesando.

Creación y regeneración de bases de datos

Una base de datos CodeQL representa una instantánea del código base en un momento dado.

  • Se crea una nueva base de datos para cada ejecución de análisis.
  • Las bases de datos no se actualizan incrementalmente.
  • Cualquier cambio en el código base requiere una nueva base de datos.

Normalmente, se vuelven a generar bases de datos cuando:

  • Se envían nuevas confirmaciones.
  • Se abren o actualizan solicitudes de incorporación de cambios.
  • Cambios de configuración de compilación.
  • Conjuntos de consultas o cambios de configuración de análisis.

Dado que la generación de bases de datos forma parte de cada análisis, es importante alinear los análisis con eventos relevantes, como solicitudes de extracción o ejecuciones programadas.

Extractores

Un extractor es una herramienta que genera los datos relacionales y la referencia de origen para cada archivo de entrada, a partir del cual se puede crear una base de datos de CodeQL. Cada lenguaje compatible con CodeQL tiene un extractor. Esta estructura garantiza que el proceso de extracción sea lo más preciso posible.

Cada extractor define su propio conjunto de opciones de configuración. Al introducir codeql resolve extractor --format=betterjson, los datos se formatean de manera similar al siguiente ejemplo:

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

Para averiguar qué opciones están disponibles para el extractor de idioma, escriba:

  • codeql resolve languages --format=betterjson o
  • codeql resolve extractor --format=betterjson.

El betterjson formato de salida también proporciona la raíz del extractor y otras opciones específicas del lenguaje.

Datos de una base de datos CodeQL

Una base de datos CodeQL es un único directorio que contiene todos los datos necesarios para el análisis. Estos datos incluyen datos relacionales, archivos de origen copiados y un esquema de base de datos específico del lenguaje que especifica las relaciones mutuas en los datos. CodeQL importa estos datos después de la extracción.

Las bases de datos CodeQL proporcionan una instantánea de los datos consultables de un idioma determinado que se extrajo de un código base. Estos datos son una representación jerárquica completa del código. Incluye:

  • Representación del árbol de sintaxis abstracta (AST).
  • Gráfico de flujo de datos.
  • Gráfico de flujo de control.

Las bases de datos se generan un idioma a la vez para los códigos base de varios idiomas. Cada idioma tiene su propio esquema de base de datos único. El esquema proporciona una interfaz entre el análisis léxico inicial durante el proceso de extracción y el análisis complejo a través de CodeQL.

Una base de datos CodeQL incluye dos tablas principales:

  • La tabla de expresiones contiene una fila para cada expresión del código fuente que CodeQL analizó durante el proceso de compilación.
  • La tabla de instrucciones contiene una fila para cada instrucción del código fuente que CodeQL analizó durante el proceso de compilación.

La biblioteca CodeQL define clases para proporcionar una capa de abstracción sobre cada una de estas tablas. Esta capa incluye las tablas Expr auxiliares relacionadas y Stmt.

Posibles errores de CodeQL

La creación de bases de datos en el flujo de trabajo de examen de código tiene algunas posibles deficiencias. En esta sección se describe específicamente el uso de la acción GitHub CodeQL.

Debe usar una matriz de lenguajes en autobuild para compilar cada uno de los lenguajes compilados indicados en la matriz. Puede usar una matriz para crear trabajos para más de una versión compatible de un lenguaje de programación, sistema operativo o herramienta.

Si no usa una matriz, autobuild intenta compilar el lenguaje compilado compatible con la mayoría de los archivos de origen del repositorio. A menudo se produce un error en el análisis de lenguajes compilados, aparte de Go, a menos que proporcione comandos explícitos para compilar el código antes de realizar el paso de análisis.

El comportamiento del paso de autobuild varía en función del sistema operativo en el que se ejecuta el extractor de lenguaje. El paso de autobuild intenta detectar automáticamente un método de compilación adecuado para el lenguaje basado en el sistema operativo. Este comportamiento puede dar lugar a resultados poco confiables para los lenguajes compilados y a menudo puede dar lugar a una ejecución con errores.

Se recomienda configurar un paso de compilación dentro del archivo de flujo de trabajo de examen de código que se ejecuta antes del análisis, en lugar de permitir que autobuild intente compilar lenguajes compilados. De este modo, el archivo de flujo de trabajo se adapta a los requisitos de compilación del sistema y del proyecto para análisis más confiables.

Puede leer más sobre lenguajes específicos y los pasos de autobuild en la documentación de Autobuild de CodeQL.

Extensión de VS Code

Puede usar Visual Studio Code (VS Code) y la extensión CodeQL para compilar y ejecutar consultas, siempre y cuando use VS Code 1.39 o posterior. Puede descargar la extensión desde Visual Studio Code Marketplace o descargar el archivo VSIX de CodeQL.

La extensión usa la CLI instalada que se encuentra en PATH si está disponible. Si no es así, la extensión administra automáticamente el acceso al archivo ejecutable de la CLI. La administración automática garantiza que la CLI sea compatible con la extensión CodeQL.