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 cien CI/CD - Ejecuta
npm auditregularmente - 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