Nota: Este artículo se migró desde el sitio web de documentación de CodeQL en enero de 2023.
Acerca de la creación de bases de datos de CodeQL
Antes de analizar el código con CodeQL, debes crear una base de datos de CodeQL que contenga todos los datos necesarios para ejecutar consultas en el código. Puedes crear bases de datos de CodeQL con la CodeQL CLI o bien descargarlos del GitHub.com.
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 de CodeQL. Las bases de datos de CodeQL contienen toda la información importante sobre un código base, que se puede analizar ejecutando consultas de CodeQL en él. GitHub crea y almacena bases de datos de CodeQL para una gran cantidad de proyectos de código abierto. Para obtener más información, consulta "Descarga de bases de datos de CodeQL desde el GitHub.com".
También puedes crear bases de datos de CodeQL por tu cuenta mediante la CodeQL CLI. Antes de generar una base de datos de CodeQL, debes hacer lo siguiente:
- Instalar y configurar la CodeQL CLI. Para obtener más información, consulta "Introducción a la CodeQL CLI".
- Consultar la versión del código base que quieres analizar. El directorio debe estar listo para compilarse, con todas las dependencias ya instaladas.
Para obtener información sobre el uso de la CodeQL CLI en un sistema de CI de terceros a fin de crear resultados que se muestren en GitHub como alertas de análisis de código, consulta Configuración de la CodeQL CLI en el sistema de CI. Para obtener información sobre la habilitación del análisis de código de CodeQL mediante GitHub Actions, consulta Configuración del análisis de código para un repositorio.
En ejecución codeql database create
Las bases de datos de CodeQL se crean ejecutando el comando siguiente desde la raíz de restauración del proyecto:
codeql database create <database> --language=<language-identifier>
Debe especificar:
<database>
: una ruta de acceso a la base de datos nueva que se va a crear. Este directorio se creará al ejecutar el comando; no se puede especificar un directorio existente.--language
: el identificador del lenguaje para el que se va a crear una base de datos. Cuando se usa con--db-cluster
, la opción acepta una lista separada por comas o se puede especificar más de una vez. CodeQL admite la creación de bases de datos para los lenguajes siguientes:
Lenguaje | Identificador |
---|---|
C/C++ | cpp |
C# | csharp |
Go | go |
Java | java |
JavaScript/TypeScript | javascript |
Python | python |
Ruby | ruby |
Nota: El análisis de CodeQL para Ruby se encuentra actualmente en versión beta. Durante el beta, el análisis para Ruby será menos exhaustivo que el análisis de CodeQL para otros lenguajes.
Puedes especificar opciones adicionales en función de la ubicación del archivo de origen, si se tiene que compilar el código y si quieres crear bases de datos de CodeQL para más de un lenguaje:
--source-root
: la carpeta raíz de los archivos de código fuente principales usados en la creación de la base de datos. De manera predeterminada, el comando supone que el directorio actual es la raíz del origen. Use esta opción para especificar otra ubicación.--db-cluster
: se usa para los códigos base de varios lenguajes cuando se quieren crear bases de datos para más de un lenguaje.--command
: se usa al crear una base de datos para uno o varios lenguajes compilados; se omite si los únicos lenguajes solicitados son Python y JavaScript. Este elemento especifica los comandos de compilación necesarios para invocar el compilador. Los comandos se ejecutan desde la carpeta actual o desde--source-root
si se especifica. Si no incluyes un elemento--command
, CodeQL intentará detectar automáticamente el sistema de compilación mediante un generador automático integrado.--no-run-unnecessary-builds
: se usa con--db-cluster
a fin de suprimir el comando de compilación para los lenguajes en donde la CodeQL CLI no necesite supervisar la compilación (por ejemplo, Python y JavaScript/TypeScript).
Puedes especificar opciones de extractor para personalizar el comportamiento de los extractores que crean bases de datos de CodeQL. Para obtener más información, consulta "Opciones de extractor".
Para obtener información detallada sobre todas las opciones que se pueden usar al crear bases de datos, consulta la documentación de referencia de creación de bases de datos.
Progreso y resultados
Los errores se notifican si hay algún problema con las opciones especificadas. En el caso de los lenguajes interpretados, el progreso de la extracción se muestra en la consola; para cada archivo de origen, notifica si la extracción se realizó correctamente o si se produjo un error. En el caso de los lenguajes compilados, la consola mostrará la salida del sistema de compilación.
Cuando la base de datos se crea correctamente, encontrarás un directorio nuevo en la ruta de acceso especificada en el comando. Si usaste la opción --db-cluster
para crear más de una base de datos, se crea un subdirectorio para cada lenguaje. Cada directorio de base de datos de CodeQL contiene varios subdirectorios, incluidos los datos relacionales (necesarios para el análisis) y un archivo de origen (una copia de los archivos de origen realizada en el momento en que se creó la base de datos), que se usa para mostrar los resultados del análisis.
Creación de bases de datos para lenguajes no compilados
La CodeQL CLI incluye extractores a fin de crear bases de datos para lenguajes no compilados, en concreto JavaScript (y TypeScript), Python y Ruby. Estos extractores se invocan automáticamente al especificar JavaScript, Python o Ruby como la opción --language
al ejecutar database create
. Al crear bases de datos para estos lenguajes, debes asegurarte de que todas las dependencias adicionales están disponibles.
Nota: Al ejecutar database create
para JavaScript, TypeScript, Python y Ruby, no debes especificar una opción --command
. De lo contrario, invalidará la invocación de extractor normal, que creará una base de datos vacía. Si creas bases de datos para varios lenguajes y uno de ellos es un lenguaje compilado, usa la opción --no-run-unnecessary-builds
a fin de omitir el comando de los lenguajes que no sea necesario compilar.
JavaScript y TypeScript
La creación de bases de datos para JavaScript no requiere dependencias adicionales, pero si el proyecto incluye archivos TypeScript, debes instalar Node.js 6.x o una versión posterior. En la línea de comandos, puedes especificar --language=javascript
para extraer archivos JavaScript y TypeScript:
codeql database create --language=javascript --source-root <folder-to-extract> <output-folder>/javascript-database
Aquí hemos especificado una ruta de acceso --source-root
, que es la ubicación donde se ejecuta la creación de la base de datos, pero no es necesariamente la raíz de restauración del código base.
De manera predeterminada, los archivos de los directorios node_modules
y bower_components
no se extraen.
Python
Al crear bases de datos para Python, debes asegurarte de lo siguiente:
- Tener Python 3 instalado y disponible para el extractor de CodeQL.
- Tener instalada la versión de Python que usa el código.
- Tener acceso al sistema de administración de empaquetado pip y poder instalar los paquetes de los que depende el código base.
- Tener instalado el módulo virtualenv de pip.
En la línea de comandos, debes especificar --language=python
. Por ejemplo:
codeql database create --language=python <output-folder>/python-database
Esto ejecuta el subcomando database create
desde la raíz de restauración del código, lo que genera una base de datos de Python nueva en <output-folder>/python-database
.
Ruby
La creación de bases de datos para Ruby no requiere dependencias adicionales. En la línea de comandos, debes especificar --language=ruby
. Por ejemplo:
codeql database create --language=ruby --source-root <folder-to-extract> <output-folder>/ruby-database
Aquí hemos especificado una ruta de acceso --source-root
, que es la ubicación donde se ejecuta la creación de la base de datos, pero no es necesariamente la raíz de restauración del código base.
Creación de bases de datos para lenguajes compilados
En el caso de los lenguajes compilados, CodeQL debe invocar el sistema de compilación necesario a fin de generar una base de datos, por lo que el método de compilación debe estar disponible para la CLI.
Detección del sistema de compilación
Nota: El análisis de CodeQL para Kotlin se encuentra actualmente en versión beta. Durante la versión beta, el análisis del código de Kotlin y la documentación complementaria no serán tan exhaustivos como para otros lenguajes.
La CodeQL CLI incluye generadores automáticos para código de C/C++, C#, Go y Java. Los generadores automáticos de CodeQL permiten compilar proyectos para lenguajes compilados sin especificar ningún comando de compilación. Cuando se invoca un generador automático, CodeQL examina el origen en busca de evidencias de un sistema de compilación e intenta ejecutar un conjunto óptimo de comandos necesarios para extraer una base de datos.
Un generador automático se invoca automáticamente cuando se ejecuta codeql database create
para un elemento --language
compilado si no se incluye una opción --command
. Por ejemplo, para un código base de Java, simplemente ejecutarías lo siguiente:
codeql database create --language=java <output-folder>/java-database
Si un código base usa un sistema de compilación estándar, basarse en un generador automático suele ser la manera más sencilla de crear una base de datos. En el caso de los orígenes que requieren pasos de compilación que no son estándar, es posible que tengas que definir de forma explícita cada paso en la línea de comandos.
Notas:
-
Si vas a compilar una base de datos de Go, instala la cadena de herramientas de Go (versión 1.11 o una posterior) y, si hay dependencias, el administrador de dependencias adecuado (por ejemplo, dep).
-
El generador automático de Go intenta detectar automáticamente el código escrito en Go en un repositorio y solo ejecuta scripts de compilación en un intento de capturar dependencias. Para forzar que CodeQL limite la extracción a los archivos que ha compilado el script de compilación, establece la variable de entorno
CODEQL_EXTRACTOR_GO_BUILD_TRACING=on
o usa la opción--command
a fin de especificar un comando de compilación.
Especificación de comandos de compilación
Los ejemplos siguientes están pensados para darte una idea de algunos de los comandos de compilación que puedes especificar para los lenguajes compilados.
Nota: La opción --command
acepta un único argumento; si necesitas usar más de un comando, especifica --command
varias veces. Si necesitas pasar subcomandos y opciones, el argumento entero debe ir entre comillas para que se interprete correctamente.
-
Proyecto de C/C++ compilado con
make
:CodeQL database create cpp-database --language=cpp --command=make
-
Proyecto de C# compilado con
dotnet build
:Es recomendable agregar
/t:rebuild
para asegurarse de que se compilará todo el código, o bien realizar un elementodotnet clean
anterior (el código que no esté compilado no se incluirá en la base de datos de CodeQL):CodeQL database create csharp-database --language=csharp --command='dotnet build /t:rebuild'
-
Ve al proyecto compilado con la variable de entorno
CODEQL_EXTRACTOR_GO_BUILD_TRACING=on
:CODEQL_EXTRACTOR_GO_BUILD_TRACING=on CodeQL database create go-database --language=go
-
Ve al proyecto compilado con un script de compilación personalizado:
CodeQL database create go-database --language=go --command='./scripts/build.sh'
-
Proyecto de Java compilado con Gradle:
# Use `--no-daemon` because a build delegated to an existing daemon cannot be detected by CodeQL: CodeQL database create java-database --language=java --command='gradle --no-daemon clean test'
-
Proyecto de Java compilado con Maven:
CodeQL database create java-database --language=java --command='mvn clean install'
-
Proyecto de Java compilado con Ant:
CodeQL database create java-database --language=java --command='ant -f build.xml'
-
Proyecto compilado con Bazel:
# Navigate to the Bazel workspace. # Before building, remove cached objects # and stop all running Bazel server processes. bazel clean --expunge # Build using the following Bazel flags, to help CodeQL detect the build: # `--spawn_strategy=local`: build locally, instead of using a distributed build # `--nouse_action_cache`: turn off build caching, which might prevent recompilation of source code # `--noremote_accept_cached`, `--noremote_upload_local_results`: avoid using a remote cache CodeQL database create new-database --language=<language> \ --command='bazel build --spawn_strategy=local --nouse_action_cache --noremote_accept_cached --noremote_upload_local_results //path/to/package:target' # After building, stop all running Bazel server processes. # This ensures future build commands start in a clean Bazel server process # without CodeQL attached. bazel shutdown
-
Proyecto compilado con un script de compilación personalizado:
CodeQL database create new-database --language=<language> --command='./scripts/build.sh'
Este comando ejecuta un script personalizado que contiene todos los comandos necesarios para compilar el proyecto.
Uso del seguimiento indirecto de la compilación
Si los generadores automáticos de la CodeQL CLI para lenguajes compilados no funcionan con el flujo de trabajo de CI y no puedes encapsular invocaciones de comandos de compilación con codeql database trace-command
, puedes usar el seguimiento indirecto de la compilación para crear una base de datos de CodeQL. A fin de usar el seguimiento indirecto de la compilación, el sistema de CI debe poder establecer variables de entorno personalizadas para cada acción de compilación.
Para crear una base de datos de CodeQL con seguimiento indirecto de la compilación, ejecuta el comando siguiente desde la raíz de desprotección del proyecto:
codeql database init ... --begin-tracing <database>
Debe especificar:
<database>
: una ruta de acceso a la base de datos nueva que se va a crear. Este directorio se creará al ejecutar el comando; no se puede especificar un directorio existente.--begin-tracing
: crea scripts que se pueden usar para configurar un entorno en el que se realizará un seguimiento de los comandos de compilación.
Puedes especificar otras opciones para el comando codeql database init
con normalidad.
Nota: Si la compilación se ejecuta en Windows, debes establecer --trace-process-level <number>
o --trace-process-name <parent process name>
a fin de que la opción apunte a un proceso de CI primario que observará todos los pasos de compilación para el código que se va a analizar.
El comando codeql database init
dará generará un mensaje:
Created skeleton <database>. This in-progress database is ready to be populated by an extractor. In order to initialise tracing, some environment variables need to be set in the shell your build will run in. A number of scripts to do this have been created in <database>/temp/tracingEnvironment. Please run one of these scripts before invoking your build command.
Based on your operating system, we recommend you run: ...
El comando codeql database init
crea <database>/temp/tracingEnvironment
con archivos que contienen variables de entorno y valores que permitirán que CodeQL realice un seguimiento de una secuencia de pasos de compilación. Estos archivos se denominan start-tracing.{json,sh,bat,ps1}
. Usa uno de estos archivos con el mecanismo del sistema de CI a fin de establecer variables de entorno para pasos futuros. Puede:
- Leer el archivo JSON, procesarlo e imprimir variables de entorno en el formato que espera el sistema de CI. Por ejemplo, Azure DevOps espera
echo "##vso[task.setvariable variable=NAME]VALUE"
. - O bien, si el sistema de CI conserva el entorno, obtén el script de
start-tracing
adecuado para establecer las variables de CodeQL en el entorno de shell del sistema de CI.
Compila el código; opcionalmente, anula las variables de entorno mediante un script de end-tracing.{json,sh,bat,ps1}
del directorio donde se almacenan los scripts de start-tracing
; y, después, ejecuta el comando codeql database finalize <database>
.
Una vez que hayas creado una base de datos de CodeQL mediante el seguimiento indirecto de la compilación, puedes trabajar con ella como con cualquier otra base de datos de CodeQL. Por ejemplo, analiza la base de datos y carga los resultados en GitHub si usas el examen de código.
Ejemplo de creación de una base de datos de CodeQL mediante el seguimiento indirecto de la compilación
En el ejemplo siguiente se muestra cómo puedes usar el seguimiento indirecto de la compilación en una canalización de Azure DevOps para crear una base de datos de CodeQL:
steps:
# Download the CodeQL CLI and query packs...
# Check out the repository ...
# Run any pre-build tasks, for example, restore NuGet dependencies...
# Initialize the CodeQL database.
# In this example, the CodeQL CLI has been downloaded and placed on the PATH.
- task: CmdLine@1
displayName: Initialize CodeQL database
inputs:
# Assumes the source code is checked out to the current working directory.
# Creates a database at `<current working directory>/db`.
# Running on Windows, so specifies a trace process level.
script: "codeql database init --language csharp --trace-process-name Agent.Worker.exe --source-root . --begin-tracing db"
# Read the generated environment variables and values,
# and set them so they are available for subsequent commands
# in the build pipeline. This is done in PowerShell in this example.
- task: PowerShell@1
displayName: Set CodeQL environment variables
inputs:
targetType: inline
script: >
$json = Get-Content $(System.DefaultWorkingDirectory)/db/temp/tracingEnvironment/start-tracing.json | ConvertFrom-Json
$json.PSObject.Properties | ForEach-Object {
$template = "##vso[task.setvariable variable="
$template += $_.Name
$template += "]"
$template += $_.Value
echo "$template"
}
# Execute the pre-defined build step. Note the `msbuildArgs` variable.
- task: VSBuild@1
inputs:
solution: '**/*.sln'
msbuildArgs: /p:OutDir=$(Build.ArtifactStagingDirectory)
platform: Any CPU
configuration: Release
# Execute a clean build, in order to remove any existing build artifacts prior to the build.
clean: True
displayName: Visual Studio Build
# Read and set the generated environment variables to end build tracing. This is done in PowerShell in this example.
- task: PowerShell@1
displayName: Clear CodeQL environment variables
inputs:
targetType: inline
script: >
$json = Get-Content $(System.DefaultWorkingDirectory)/db/temp/tracingEnvironment/end-tracing.json | ConvertFrom-Json
$json.PSObject.Properties | ForEach-Object {
$template = "##vso[task.setvariable variable="
$template += $_.Name
$template += "]"
$template += $_.Value
echo "$template"
}
- task: CmdLine@2
displayName: Finalize CodeQL database
inputs:
script: 'codeql database finalize db'
# Other tasks go here, for example:
# `codeql database analyze`
# then `codeql github upload-results` ...
Descarga de bases de datos desde el GitHub.com
GitHub almacena bases de datos de CodeQL para más de 200 000 repositorios en el GitHub.com, que puedes descargar mediante la API REST. La lista de repositorios está creciendo y evolucionando constantemente a fin de garantizar que incluye los códigos base más interesantes para la investigación de seguridad.
Puedes comprobar si un repositorio tiene bases de datos de CodeQL disponibles para su descarga mediante el punto de conexión /repos/<owner>/<repo>/code-scanning/codeql/databases
. Por ejemplo, para comprobar si hay bases de datos de CodeQL con la GitHub CLI, ejecutarías lo siguiente:
gh api /repos/<owner>/<repo>/code-scanning/codeql/databases/
Este comando devuelve información sobre cualquier base de datos de CodeQL que está disponible para un repositorio, incluido el lenguaje que representa la base de datos y cuándo se actualizó por última vez la base de datos. Si no hay bases de datos de CodeQL disponibles, la respuesta está vacía.
Cuando hayas confirmado que existe una base de datos de CodeQL para el lenguaje para el que muestras interés, puedes descargarla con el comando siguiente:
gh api /repos/<owner>/<repo>/code-scanning/codeql/databases/<language> -H 'Accept: application/zip' > path/to/local/database.zip
Para obtener más información, consulta la documentación del punto de conexión de base de datos Get de CodeQL.
Para poder ejecutar un análisis con la CodeQL CLI, debes descomprimir las bases de datos.