Escribir una comilla simple ' en cualquier campo de texto y observar si aparece un error de base de datos es una verificación básica de inyección SQL que lleva diez segundos y no requiere herramientas de seguridad. Cambiar el ID de recurso de otro usuario en la URL para ver si puedes acceder a él detecta broken object-level authorization, una de las vulnerabilidades de API más comunes, y ya está dentro del alcance de QA durante el testing funcional. Este artículo cubre las verificaciones de autenticación, autorización, validación de inputs y cookies que los QA engineers pueden ejecutar sin especialistas, con ejemplos de Playwright para las que vale la pena automatizar.

Qué pueden probar los QA engineers sin herramientas especializadas

Autenticación y gestión de sesiones

Los bugs de seguridad más comunes están en los flujos de autenticación. Prueba esto durante el testing funcional regular:

#### Protección contra fuerza bruta

Intenta enviar la contraseña incorrecta 10 veces. ¿La app bloquea la cuenta o aplica rate limiting? Si no lo hace, es un hallazgo.

#### Fijación de sesión

Inicia sesión. Copia la cookie de sesión. Cierra sesión. Intenta usar la cookie de sesión antigua. Si sigue funcionando, las sesiones no se invalidan al cerrar sesión.

#### Duración del "recordarme"

Activa "recordarme", cierra el navegador, vuelve a abrirlo después de 30 días (o adelanta el reloj del sistema). ¿La sesión sigue funcionando? ¿Por cuánto tiempo?

#### Reutilización de token de reseteo de contraseña

Solicita un email de reseteo. Usa el link para resetear. Intenta usar el link de nuevo. Debería ser inválido. Si funciona dos veces, es un bug.

#### Sesiones concurrentes

Inicia sesión en dos navegadores diferentes simultáneamente. ¿Debería invalidarse alguna de las sesiones?

Autorización (control de acceso)

Acá es donde se esconden la mayoría de los bugs graves:

#### Escalada horizontal de privilegios

Crea dos cuentas (usuario A y usuario B). Como usuario A, crea algún recurso (un pedido, un documento, un ítem de perfil). Anota el ID del recurso en la URL. Inicia sesión como usuario B. Intenta acceder, editar o eliminar el recurso del usuario A por ID. Si puedes hacerlo, es un bug de broken object-level authorization (BOLA), una de las vulnerabilidades de API más comunes.

GET /api/orders/12345   ← pedido del usuario A

Inicia sesión como usuario B y accede a la misma URL. ¿Qué pasa?

#### Escalada vertical de privilegios

Intenta acceder a funciones de administrador como usuario regular. Verifica URLs de administrador (/admin, /dashboard/admin, /api/admin/*) sin credenciales de administrador.

#### IDOR en respuestas de API

¿La API devuelve solo los datos que el usuario actual debería ver? Verifica si una llamada de API de un usuario regular devuelve datos de otros usuarios en algún campo.

Validación de inputs

Cada campo de formulario es un punto potencial de inyección:

#### Inyección SQL (prueba básica)

Ingresa ' (comilla simple) en cualquier campo de texto. ¿La app devuelve un error de base de datos? Si sí, probablemente es vulnerable.

#### XSS (prueba básica)

Ingresa en cualquier campo que muestre contenido a los usuarios (campos de nombre, comentarios, direcciones). Si aparece una caja de alerta, es XSS almacenado.

#### Path traversal

Intenta ../../../etc/passwd en campos de nombre de archivo o parámetros de URL. Debería devolver un error, no el contenido del archivo.

Estas pruebas manuales son rápidas y detectan los problemas más obvios. No reemplazan el escaneo de seguridad automatizado, pero vale la pena ejecutarlas en cada funcionalidad nueva.

HTTPS y cookies

Verifica en las DevTools del navegador:

  • ¿El sitio se sirve sobre HTTPS? ¿HTTP redirige a HTTPS?
  • ¿Las cookies de sesión están marcadas como HttpOnly (no accesibles desde JavaScript)?
  • ¿Las cookies de sesión están marcadas como Secure (solo se envían sobre HTTPS)?
  • ¿SameSite está configurado como Strict o Lax en las cookies de autenticación?

En Playwright:

test('la cookie de auth tiene flags de seguridad', async ({ page, context }) => {
  await page.goto('/login');
  // ... realizar login
  
  const cookies = await context.cookies();
  const sessionCookie = cookies.find(c => c.name === 'session_token');

  expect(sessionCookie?.httpOnly).toBe(true);
  expect(sessionCookie?.secure).toBe(true);
  expect(sessionCookie?.sameSite).toMatch(/strict|lax/i);
});

Mensajes de error y divulgación de información

Los mensajes de error demasiado informativos son un problema de seguridad:

  • "Usuario no encontrado" vs "Credenciales inválidas": el primero le dice a los atacantes qué cuentas existen
  • Stack traces en respuestas de producción
  • Rutas internas del servidor, nombres de bases de datos o versiones de librerías en mensajes de error
  • Respuestas de API que incluyen campos como passwordHash, internalId o flags de administrador

Integrar seguridad en tu proceso de testing

Escaneo base de OWASP ZAP

OWASP ZAP es gratuito y puede correr como escáner pasivo junto a tus tests de Playwright. El modo de escaneo base rastrea tu app y señala problemas obvios:

# .github/workflows/security.yml
- name: ZAP Baseline Scan
  uses: zaproxy/action-baseline@v0.10.0
  with:
    target: 'https://staging.myapp.com'
    rules_file_name: '.zap/rules.tsv'

Esto detecta cosas como encabezados de seguridad faltantes, cookies inseguras e información del servidor expuesta, sin que tengas que escribir código de test.

Verificación de encabezados de seguridad

Encabezados que tu app debería enviar:

Content-Security-Policy: default-src 'self'
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Strict-Transport-Security: max-age=31536000; includeSubDomains
Referrer-Policy: strict-origin-when-cross-origin

Pruébalos en Playwright:

test('los encabezados de seguridad están presentes', async ({ request }) => {
  const response = await request.get('https://myapp.com');
  const headers = response.headers();

  expect(headers['x-content-type-options']).toBe('nosniff');
  expect(headers['x-frame-options']).toBe('DENY');
  expect(headers['strict-transport-security']).toContain('max-age=');
});

Qué deben pasar los QA engineers a los especialistas en seguridad

Algunos tipos de testing de seguridad requieren habilidades y herramientas especializadas:

  • Pruebas de penetración completas
  • Análisis de binarios
  • Revisión de criptografía
  • Seguridad de infraestructura (config de cloud, segmentación de red)
  • Testing de ingeniería social

Cuando encuentras un posible problema de seguridad a través del testing manual, documéntalo claramente (pasos de reproducción, impacto potencial) y escálalo a tu equipo de seguridad o regístralo como un bug de alta severidad. No intentes probar la explotabilidad por tu cuenta: tu trabajo es encontrarlo, no explotarlo.

La mejor postura de seguridad es la defensa en profundidad: QA detectando los problemas obvios durante el desarrollo, escáneres automatizados detectando los problemas sistemáticos en CI, y especialistas haciendo la revisión profunda antes de los releases importantes.

→ See also: Testing de Seguridad para Ingenieros QA: Lo Que Necesitas Saber | El Ciclo de Vida del Desarrollo de Software para Ingenieros QA | Testing Basado en Riesgos: Priorizar Qué Testear Cuando No Puedes Testar Todo