Ir al contenido

CodeQL

CodeQL es la herramienta de análisis estático de GitHub para encontrar vulnerabilidades de seguridad y problemas de calidad de código utilizando consultas semánticas y análisis semántico.

Instalación

macOS

# Instalación con Homebrew
brew install codeql

# Descarga manual
wget https://github.com/github/codeql-cli-releases/releases/download/v2.16.0/codeql-osx64.zip
unzip codeql-osx64.zip
export PATH=$PATH:$HOME/codeql

Linux

# Ubuntu/Debian
wget https://github.com/github/codeql-cli-releases/releases/download/v2.16.0/codeql-linux64.zip
unzip codeql-linux64.zip
sudo mv codeql /usr/local/bin/

# Verificar instalación
codeql --version

Windows

# Descargar desde GitHub releases
# https://github.com/github/codeql-cli-releases/releases
# Extraer y agregar a PATH

Operaciones de Base de Datos

Crear Base de Datos CodeQL

# Crear base de datos para un repositorio de GitHub
codeql database create <database-name> --language=<language> --source-root=<path>

# Ejemplo: Crear base de datos de JavaScript
codeql database create my-db --language=javascript --source-root=./src

# Crear base de datos multilenguaje
codeql database create my-db --language=java,javascript --source-root=./src

# Crear base de datos con comando explícito
codeql database create my-db \
  --language=python \
  --command="python -m pip install -r requirements.txt" \
  --source-root=./

# Con esquema de base de datos personalizado
codeql database create my-db \
  --language=cpp \
  --source-root=./src \
  --db-scheme=/custom/db-scheme.yml

Gestionar Bases de Datos

# Listar bases de datos
codeql database list

# Obtener información de base de datos
codeql database info <database>

# Limpiar bases de datos no utilizadas
codeql database cleanup <database>

# Eliminar base de datos
rm -rf <database-path>

# Empaquetar base de datos para compartir
codeql database bundle <database> --output=<bundle.zip>

# Desempaquetar base de datos
codeql database unbundle <bundle.zip> --output=<database>

Ejecutar Consultas

Ejecución Básica de Consultas

# Ejecutar consulta individual en base de datos
codeql query run <query.ql> --database=<database>

# Ejecutar suite de consultas
codeql query run <query-suite.yaml> --database=<database>

# Ejecutar consulta y guardar resultados como CSV
codeql query run <query.ql> --database=<database> --output=<results.csv>

# Ejecutar con salida JSON
codeql query run <query.ql> --database=<database> --output=<results.json> --format=json

Consultas de Seguridad Integradas

# Ejecutar consultas de seguridad y calidad predeterminadas
codeql database analyze <database> security-and-quality --format=sarif-latest --output=results.sarif

# Analizar con suite de consultas personalizada
codeql database analyze <database> <path/to/queries> \
  --format=sarif-latest \
  --output=results.sarif

# Analizar lenguaje específico
codeql database analyze <database> codeql/java-queries --format=csv --output=results.csv

# Análisis enfocado en CWE
codeql database analyze <database> codeql-suites/javascript-security-and-quality.qls

Comandos Específicos de Lenguaje

JavaScript/TypeScript

# Crear base de datos de JavaScript
codeql database create js-db --language=javascript --source-root=.

# Ejecutar análisis de seguridad
codeql database analyze js-db codeql/javascript-queries:security-and-quality --format=sarif-latest

# Verificar inyección SQL
codeql query run \
  --database=js-db \
  <path-to-query>/sql-injection.ql

Python

# Crear base de datos de Python
codeql database create py-db --language=python --source-root=.

# Análisis de seguridad
codeql database analyze py-db codeql/python-queries:security --format=sarif-latest

# Detección de recorrido de directorio
codeql query run \
  --database=py-db \
  <path-to-query>/path-injection.ql

Java

# Crear base de datos de Java con Maven
codeql database create java-db \
  --language=java \
  --command="mvn clean install" \
  --source-root=.

# Con Gradle
codeql database create java-db \
  --language=java \
  --command="gradle build" \
  --source-root=.

# Escaneo de seguridad
codeql database analyze java-db codeql/java-queries:security-and-quality

C/C++

# Crear base de datos de C++ con make
codeql database create cpp-db \
  --language=cpp \
  --command="make" \
  --source-root=.

# Con CMake
codeql database create cpp-db \
  --language=cpp \
  --command="cmake . && make" \
  --source-root=.

Desarrollo de Consultas

Crear Consultas Personalizadas

# Iniciar desarrollo de consultas
cat > select-sinks.ql << 'EOF'
import cpp

from FunctionCall fc
where fc.getTarget().getName() = "printf"
select fc
EOF

# Ejecutar consulta personalizada
codeql query run select-sinks.ql --database=cpp-db

Estructura de Consulta

import java

class SQLInjectionVulnerability extends DataFlow::FlowSink {
  SQLInjectionVulnerability() {
    asExpr() instanceof MethodAccess and
    asExpr().(MethodAccess).getMethod().hasName("execute")
  }
}

from DataFlow::PathNode source, DataFlow::PathNode sink
where TaintTracking::localTaintStep(source.getNode(), sink.getNode())
select source.getNode(), source, sink, "Potential SQL injection"

Probar Consultas

# Ejecutar pruebas de consulta
codeql test run <test-dir>

# Probar con salida detallada
codeql test run <test-dir> --verbose

# Probar archivo de prueba específico
codeql test run <test-file.ql>

Integración con CI/CD

GitHub Actions

name: CodeQL Analysis
on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  analyze:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Initialize CodeQL
        uses: github/codeql-action/init@v2
        with:
          languages: 'javascript,python'

      - name: Build
        run: |
          npm install
          npm run build

      - name: Perform CodeQL Analysis
        uses: github/codeql-action/analyze@v2

Integración Manual con CI

#!/bin/bash
set -e

# Crear base de datos
codeql database create codeql-db --language=javascript --source-root=.

# Ejecutar análisis
codeql database analyze codeql-db security-and-quality --format=sarif-latest --output=results.sarif

# Subir resultados
curl -H "Authorization: token $GITHUB_TOKEN" \
  -F "payload=@results.sarif" \
  "https://api.github.com/repos/$GITHUB_REPOSITORY/code-scanning/sarif"

Resolución de Problemas

Problemas Comunes

La creación de base de datos falla

# Verificar soporte de lenguaje
codeql describe languages

# Verificar comando de compilación
codeql database create db \
  --language=java \
  --command="mvn clean install" \
  --source-root=. \
  --verbose

Tiempo de espera de consulta

# Aumentar tiempo de espera (predeterminado 3600 segundos)
codeql query run query.ql --database=db --timeout=7200

Problemas de memoria

# Aumentar tamaño de heap
export CODEQL_JAVA_TOOL_OPTIONS=-Xmx4g
codeql database analyze db query-suite

No se encontraron resultados

# Verificar que la base de datos se creó correctamente
codeql database info <database>

# Verificar estadísticas de base de datos
codeql database log-summary <database>

# Ejecutar consulta de prueba simple
codeql query run tests/test-query.ql --database=db

Flujos de Trabajo Avanzados

Análisis de Taint Tracking

import javascript
import DataFlow
import TaintTracking

class Configuration extends TaintTracking::Configuration {
  Configuration() { this = "UserControlledFileName" }

  override predicate isSource(DataFlow::Node source) {
    source instanceof RemoteFlowSource
  }

  override predicate isSink(DataFlow::Node sink) {
    sink = any(FileSystemAccess fs).getAPathArgument()
  }
}

from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
where cfg.hasFlowPath(source, sink)
select sink, "User input flows to filesystem access"

Configuración de Flujo de Datos

import java
import DataFlow
import FlowSources

class MyConfiguration extends TaintTracking::Configuration {
  MyConfiguration() { this = "MyDataFlow" }

  override predicate isSource(DataFlow::Node n) {
    n instanceof RemoteFlowSource
  }

  override predicate isSink(DataFlow::Node n) {
    exists(MethodAccess m |
      m.getMethod().hasName("exec") and
      n.asExpr() = m.getAnArgument()
    )
  }

  override predicate isAdditionalTaintStep(DataFlow::Node n1, DataFlow::Node n2) {
    any()
  }
}

Optimización de Rendimiento

Ajuste de Base de Datos

# Crear base de datos con optimizaciones
codeql database create db \
  --language=javascript \
  --source-root=. \
  --dbscheme=/path/to/optimized-scheme.yml

# Usar máximo de threads para análisis
codeql database analyze db \
  security-and-quality \
  --threads=0  # Usar todos los núcleos de CPU disponibles

Optimización de Consultas

# Ejecutar consultas de prefiltrado
codeql query run prefilter.ql --database=db

# Analizar solo archivos modificados (si se hace seguimiento)
codeql database analyze db \
  --threads=4 \
  --sarif-category="javascript" \
  security-and-quality

Variables de Entorno

VariableDescripción
CODEQL_HOMEDirectorio de instalación
CODEQL_JAVA_TOOL_OPTIONSOpciones de JVM (ej. -Xmx4g)
GITHUB_TOKENAutenticación de API de GitHub
CODEQL_THREADSNúmero de threads para procesamiento

Mejores Prácticas

  • Guardar bases de datos en control de versiones para reproducibilidad
  • Usar versiones consistentes de lenguaje y suite de consultas
  • Incluir CodeQL en hooks pre-commit para detección temprana
  • Actualizar regularmente CLI de CodeQL y paquetes de consultas
  • Documentar consultas personalizadas con comentarios claros
  • Probar consultas contra vulnerabilidades reales
  • Usar salida SARIF para integración con otras herramientas
  • Ejecutar análisis completo periódicamente, no solo cambios
  • Monitorear tasas de falsos positivos y ajustar consultas
  • Archivar resultados históricos para análisis de tendencias

Recursos


Última actualización: 2025-03-30