🔒 Developer Cookbook - FASE 4: Code Review y Análisis Estático

Recetas prácticas para construir aplicaciones seguras, monitoreadas y observables


📚 Tabla de Contenidos

  1. Receta 4.7: Static Analysis - SonarQube y CodeQL
  2. Receta 4.8: Dependency Scanning

Code Review y Análisis Estático

Receta 4.7: Static Analysis - SonarQube y CodeQL

SonarQube - Configuración:

# sonar-project.properties
sonar.projectKey=myapp
sonar.projectName=My Application
sonar.projectVersion=1.0

# Paths
sonar.sources=src
sonar.tests=tests
sonar.python.coverage.reportPaths=coverage.xml

# Exclusions
sonar.exclusions=**/node_modules/**,**/vendor/**,**/*.test.js

# Coverage exclusions
sonar.coverage.exclusions=**/*.test.js,**/tests/**

# Quality Gate
sonar.qualitygate.wait=true

GitHub Actions con SonarQube:

# .github/workflows/sonarqube.yml
name: SonarQube Analysis

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

jobs:
  sonarqube:
    name: SonarQube Scan
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0  # Shallow clones deshabilitados para mejor análisis

      - name: Setup Python
        uses: actions/setup-python@v4
        with:
          python-version: '3.11'

      - name: Install dependencies
        run: |
          pip install -r requirements.txt
          pip install pytest pytest-cov

      - name: Run tests with coverage
        run: pytest --cov=src --cov-report=xml

      - name: SonarQube Scan
        uses: sonarsource/sonarqube-scan-action@master
        env:
          SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
          SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}

      - name: Check Quality Gate
        uses: sonarsource/sonarqube-quality-gate-action@master
        timeout-minutes: 5
        env:
          SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}

CodeQL - Análisis de seguridad:

# .github/workflows/codeql.yml
name: CodeQL Analysis

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
  schedule:
    - cron: '0 0 * * 1'  # Weekly scan

jobs:
  analyze:
    name: Analyze
    runs-on: ubuntu-latest

    permissions:
      actions: read
      contents: read
      security-events: write

    strategy:
      fail-fast: false
      matrix:
        language: ['python', 'javascript']

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Initialize CodeQL
        uses: github/codeql-action/init@v2
        with:
          languages: ${{ matrix.language }}
          queries: security-extended

      - name: Autobuild
        uses: github/codeql-action/autobuild@v2

      - name: Perform CodeQL Analysis
        uses: github/codeql-action/analyze@v2
        with:
          category: "/language:${{ matrix.language }}"

Custom CodeQL Queries:

/**
 * @name Hardcoded credentials
 * @description Detects hardcoded passwords and API keys
 * @kind problem
 * @problem.severity error
 * @id python/hardcoded-credentials
 */

import python

from StrConst str
where
  (
    str.getText().regexpMatch("(?i).*(password|passwd|pwd)\\s*=\\s*['\"][^'\"]+['\"].*") or
    str.getText().regexpMatch("(?i).*(api_key|apikey|secret|token)\\s*=\\s*['\"][^'\"]+['\"].*")
  )
  and not str.getText().regexpMatch(".*=\\s*['\"]\\$\\{.*") // Excluir variables de entorno
select str, "Potential hardcoded credential found"

Receta 4.8: Dependency Scanning

Dependabot Configuration:

# .github/dependabot.yml
version: 2
updates:
  # Python dependencies
  - package-ecosystem: "pip"
    directory: "/"
    schedule:
      interval: "weekly"
    open-pull-requests-limit: 10
    reviewers:
      - "security-team"
    labels:
      - "dependencies"
      - "security"

    # Ignorar patches menores de dev dependencies
    ignore:
      - dependency-name: "*"
        update-types: ["version-update:semver-patch"]

  # NPM dependencies
  - package-ecosystem: "npm"
    directory: "/frontend"
    schedule:
      interval: "weekly"
    versioning-strategy: increase

  # Docker
  - package-ecosystem: "docker"
    directory: "/"
    schedule:
      interval: "weekly"

  # GitHub Actions
  - package-ecosystem: "github-actions"
    directory: "/"
    schedule:
      interval: "weekly"

Snyk - Vulnerability Scanning:

# .github/workflows/snyk.yml
name: Snyk Security

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  security:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Run Snyk to check for vulnerabilities
        uses: snyk/actions/python@master
        env:
          SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
        with:
          args: --severity-threshold=high

      - name: Upload result to GitHub Code Scanning
        uses: github/codeql-action/upload-sarif@v2
        with:
          sarif_file: snyk.sarif

OWASP Dependency-Check:

# Instalar
wget https://github.com/jeremylong/DependencyCheck/releases/download/v8.0.0/dependency-check-8.0.0-release.zip
unzip dependency-check-8.0.0-release.zip

# Ejecutar scan
./dependency-check/bin/dependency-check.sh \
  --project "MyApp" \
  --scan ./src \
  --format HTML \
  --format JSON \
  --out ./reports

# Con npm audit
npm audit --json > npm-audit.json

# Fix automático
npm audit fix
npm audit fix --force  # Acepta breaking changes

Safety (Python):

# Instalar
pip install safety

# Scan
safety check

# Con requirements.txt
safety check -r requirements.txt

# Output JSON
safety check --json > safety-report.json

# Ignorar vulnerabilidades específicas
safety check --ignore 12345

Versión: 1.0 Fecha: 2024 Autor: Roadmap del Desarrollador del Futuro Licencia: Uso educativo