Skip to content
SP StackPractices
beginner Por StackPractices

Security Headers

Fortalece aplicaciones web con HTTP security headers: CSP, HSTS, X-Frame-Options y una lista de verificación completa de headers de seguridad.

Temas: security

Nota para desarrolladores hispanohablantes: Esta guía incluye ejemplos y convenciones de nomenclatura adaptadas a equipos que trabajan en español. Cuando existen diferencias significativas en terminología técnica entre el inglés y el español, se indican explícitamente para facilitar la comunicación en equipos multiculturales.

Visión General

Los HTTP security headers son la primera línea de defensa para aplicaciones web. Instruyen a los navegadores sobre cómo comportarse al renderizar tu sitio — bloqueando XSS, previniendo clickjacking, forzando HTTPS y controlando qué recursos externos pueden cargarse. Configurados correctamente, pueden detener clases enteras de ataques sin cambiar una línea de código de aplicación.

Cuándo Usar

Usa este recurso cuando:

  • Fortaleces aplicaciones web en producción contra ataques comunes basados en navegador
  • Te preparas para auditorías de seguridad que verifican headers seguros de OWASP
  • Sirves contenido generado por usuarios que podría contener scripts maliciosos
  • Embebes tu aplicación en sitios de terceros vía iframes

Solución

Express.js Security Headers Middleware

const helmet = require('helmet');

app.use(helmet({
  contentSecurityPolicy: {
    directives: {
      defaultSrc: ["'self'"],
      scriptSrc: ["'self'", "'unsafe-inline'", "https://analytics.example.com"],
      styleSrc: ["'self'", "https://fonts.googleapis.com"],
      imgSrc: ["'self'", "data:", "https://cdn.example.com"],
      connectSrc: ["'self'", "https://api.example.com"],
      fontSrc: ["'self'", "https://fonts.gstatic.com"],
      frameAncestors: ["'none'"]
    }
  },
  hsts: {
    maxAge: 31536000,
    includeSubDomains: true,
    preload: true
  },
  referrerPolicy: { policy: 'strict-origin-when-cross-origin' }
}));

Nginx Security Headers

server {
    add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline';" always;
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
    add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;

    location / {
        proxy_pass http://backend;
    }
}

Security Header Audit Script (Bash)

#!/bin/bash
URL="https://example.com"

echo "Checking security headers for $URL..."
curl -sI "$URL" | grep -iE \
  "(content-security-policy|strict-transport-security|x-content-type-options|x-frame-options|referrer-policy|permissions-policy)"

Explicación

Headers esenciales:

HeaderPropósitoRiesgo si Falta
Content-Security-Policy (CSP)Controla scripts/styles cargadosXSS vía tags <script> inyectados
Strict-Transport-Security (HSTS)Fuerza HTTPSAtaques de SSL stripping
X-Content-Type-OptionsPreviene MIME sniffingDrive-by downloads vía content types falsos
X-Frame-OptionsBloquea clickjackingAtaques de UI redressing
Referrer-PolicyControla filtración de referrerURLs sensibles expuestas a terceros
Permissions-PolicyRestringe APIs del navegadorAcceso no autorizado a cámara, micrófono, geolocalización

Variantes

FrameworkLibreríaFacilidad
ExpressHelmetUna línea
Fastify@fastify/helmetPlugin
Djangodjango-cspMiddleware
SpringSpring SecurityConfiguración
Railssecure_headersGem
NginxNativoManual

Mejores Prácticas

  • Empieza con CSP report-only: Content-Security-Policy-Report-Only logea violaciones sin bloquear
  • Usa nonce para scripts inline: <script nonce="random-value"> en lugar de 'unsafe-inline'
  • Testea antes de enforcear: CSP puede romper widgets de terceros, formas de pago y analytics
  • Envía a lista de preload HSTS: Incluye tu dominio en listas de preload de browsers para HTTPS automático
  • Configura frame ancestors apropiadamente: Usa CSP frame-ancestors en lugar del legacy X-Frame-Options

Errores Comunes

  1. CSP demasiado permisivo: default-src * permite cualquier dominio ejecutar scripts
  2. Faltando en responses de API: Los browsers ignoran headers en páginas 404/500, pero los atacantes las usan
  3. Olvidando endpoints de API: Las APIs JSON deberían enviar CORS y CSP headers
  4. Violaciones sin reporte: Sin report-uri, no sabrás cuando contenido legítimo está bloqueado
  5. Headers inconsistentes: Proxy Nginx sobreescribiendo headers de aplicación crea gaps

Preguntas Frecuentes

P: ¿Los security headers protegen APIs? R: Parcialmente. CORS, HSTS y CSP importan para clientes de browser. Para APIs machine-to-machine, enfócate en autenticación y TLS.

P: ¿CSP romperá mi analytics? R: Solo si olvidas whitelistear tu dominio de analytics. Agrégalo a script-src y connect-src.

P: ¿Cuál es la diferencia entre X-Frame-Options y CSP frame-ancestors? R: CSP frame-ancestors es el estándar moderno. X-Frame-Options está deprecado pero útil para browsers antiguos.