TechLead
Lección 8 de 9
5 min de lectura
Seguridad Web

Seguridad de Dependencias

Mantén tus dependencias seguras con escaneo de vulnerabilidades, archivos de bloqueo y actualizaciones automatizadas.

Gestionando la Seguridad de Dependencias

Las dependencias de terceros son un vector de ataque importante. Los ataques a la cadena de suministro, paquetes vulnerables y código malicioso pueden comprometer toda tu aplicación.

Escaneo de Vulnerabilidades

npm audit

# Verificar vulnerabilidades
npm audit

# Obtener salida JSON para CI/CD
npm audit --json

# Arreglar automáticamente donde sea posible
npm audit fix

# Forzar arreglo (puede incluir cambios breaking)
npm audit fix --force

# Solo verificar dependencias de producción
npm audit --production

Snyk

# Instalar Snyk
npm install -g snyk

# Autenticarse
snyk auth

# Probar vulnerabilidades
snyk test

# Monitorear proyecto continuamente
snyk monitor

# Arreglar vulnerabilidades
snyk fix

Archivos de Bloqueo

# Siempre commit los archivos de bloqueo
# package-lock.json (npm)
# yarn.lock (Yarn)
# pnpm-lock.yaml (pnpm)

# Usar versiones exactas en CI
npm ci  # En lugar de npm install

# Verificar integridad
npm ci --ignore-scripts

Actualizaciones Automatizadas con Dependabot

# .github/dependabot.yml
version: 2
updates:
  - package-ecosystem: "npm"
    directory: "/"
    schedule:
      interval: "weekly"
    open-pull-requests-limit: 10

    # Agrupar actualizaciones minor y patch
    groups:
      minor-and-patch:
        update-types:
          - "minor"
          - "patch"

    # Ignorar paquetes específicos
    ignore:
      - dependency-name: "aws-sdk"
        update-types: ["version-update:semver-major"]

    # Solo actualizaciones de seguridad
    # schedule:
    #   interval: "daily"
    # open-pull-requests-limit: 20

Configuración de Renovate Bot

// renovate.json
{
  "$schema": "https://docs.renovatebot.com/renovate-schema.json",
  "extends": [
    "config:base",
    ":semanticCommits",
    "schedule:weekly"
  ],
  "packageRules": [
    {
      "matchUpdateTypes": ["minor", "patch"],
      "groupName": "actualizaciones minor y patch",
      "automerge": true
    },
    {
      "matchPackagePatterns": ["eslint", "prettier"],
      "groupName": "herramientas de linting"
    },
    {
      "matchDepTypes": ["devDependencies"],
      "automerge": true
    }
  ],
  "vulnerabilityAlerts": {
    "enabled": true,
    "labels": ["security"]
  }
}

Verificación de Script Pre-instalación

// package.json
{
  "scripts": {
    "preinstall": "npx npm-run-all check:*",
    "check:audit": "npm audit --audit-level=high",
    "check:licenses": "license-checker --production --onlyAllow 'MIT;Apache-2.0;BSD-2-Clause;BSD-3-Clause;ISC'"
  }
}

Usando npm-shrinkwrap para Producción

# Crear archivo shrinkwrap (más estricto que package-lock.json)
npm shrinkwrap

# Esto crea npm-shrinkwrap.json que:
# - Tiene precedencia sobre package-lock.json
# - Se publica con el paquete
# - Asegura árbol de dependencias exacto en producción

Integridad de Subrecursos (SRI) para CDN

<!-- Siempre usa SRI al cargar desde CDN -->
<script
  src="https://cdn.example.com/library.js"
  integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
  crossorigin="anonymous"
></script>

<link
  rel="stylesheet"
  href="https://cdn.example.com/styles.css"
  integrity="sha384-..."
  crossorigin="anonymous"
>
# Generar hash SRI
echo -n "console.log('hello');" | openssl dgst -sha384 -binary | openssl base64 -A

# O usa srihash.org

Registro Privado

# .npmrc para registro privado
registry=https://registry.npmjs.org/
@miempresa:registry=https://npm.miempresa.com/

# Verdaccio para registro auto-hospedado
npm install -g verdaccio
verdaccio

# Publicar a registro privado
npm publish --registry https://npm.miempresa.com/

Workflow de Seguridad en GitHub Actions

# .github/workflows/security.yml
name: Verificación de Seguridad

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
  schedule:
    - cron: '0 0 * * *'  # Diario

jobs:
  audit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Configurar Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - name: Instalar dependencias
        run: npm ci

      - name: Ejecutar npm audit
        run: npm audit --audit-level=high

      - name: Ejecutar Snyk
        uses: snyk/actions/node@master
        env:
          SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
        with:
          args: --severity-threshold=high

      - name: Verificar licencias
        run: |
          npx license-checker --production --onlyAllow 'MIT;Apache-2.0;BSD-2-Clause;BSD-3-Clause;ISC'

Mejores Prácticas

  • Siempre commit los archivos de bloqueo
  • Usa npm ci en CI/CD
  • Ejecuta npm audit regularmente
  • Configura actualizaciones automatizadas de dependencias
  • Usa SRI para recursos CDN
  • Revisa cambios de dependencias en PRs
  • Minimiza dependencias (prefiere biblioteca estándar)
  • Verifica salud del paquete antes de instalar
  • Usa paquetes con scope para código interno
  • Considera usar un registro privado

Continuar Aprendiendo