Módulo 2 de 10

Módulo 2: Cómo funciona la web por dentro (HTTP, sesiones y Burp)

Módulo 2: Cómo funciona la web por dentro (HTTP, sesiones y Burp)

Antes de explotar cualquier vulnerabilidad, necesitas entender el lenguaje que hablan los navegadores y los servidores.
Todo lo que ocurre cuando visitas una web —iniciar sesión, comprar un producto, enviar un formulario— se reduce a un
intercambio de mensajes HTTP. Un pentester web que no domina HTTP a fondo es como un electricista que no conoce la
corriente alterna: puede seguir pasos, pero no entiende qué está haciendo.

Este módulo cubre la anatomía completa de HTTP/HTTPS, las cookies y las sesiones, la Same-Origin Policy, CORS y TLS,
y termina con una práctica guiada usando Burp Suite Community sobre
OWASP Juice Shop —un laboratorio vulnerable diseñado expresamente para aprender.
Todos los conceptos que aparecen aquí son la base del
curso completo de hacking web.

Aviso legal y ético (obligatorio leer).
Las técnicas de este módulo son para uso exclusivo en laboratorios propios o entornos autorizados
expresamente por escrito
(OWASP Juice Shop, DVWA, PortSwigger Web Security Academy, máquinas virtuales
propias). En España, acceder sin autorización a sistemas informáticos ajenos constituye delito tipificado en los
artículos 197 bis y siguientes del Código Penal, con penas de hasta 5 años de prisión. Nunca practiques estas
técnicas contra sistemas reales de terceros.

1. Anatomía de HTTP: petición y respuesta

HTTP (HyperText Transfer Protocol) es un protocolo de capa de aplicación, sin estado (stateless), basado
en texto. Opera sobre TCP: el cliente abre una conexión TCP al servidor, envía un mensaje de petición, y el servidor
responde con otro mensaje. En HTTP/1.1 la conexión puede reutilizarse; en HTTP/2 se multiplexa.

Estructura de una petición HTTP

Una petición tiene tres partes: línea de solicitud, cabeceras y
cuerpo opcional (separado de las cabeceras por una línea en blanco).

POST /login HTTP/1.1
Host: 192.168.1.50:3000
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) Firefox/126.0
Accept: application/json, text/plain, */*
Content-Type: application/json
Content-Length: 47
Cookie: language=es; welcomebanner_status=dismiss

{"email":"user@example.com","password":"1234"}
  • Línea de solicitud: método + ruta + versión del protocolo.
  • Host: dominio (o IP:puerto) del servidor destino. Obligatorio en HTTP/1.1.
  • User-Agent: identifica el cliente (navegador, versión, SO). Puede falsificarse.
  • Content-Type: formato del cuerpo (application/json, application/x-www-form-urlencoded, multipart/form-data…).
  • Cookie: pares nombre=valor separados por ; que el navegador envía automáticamente.

Estructura de una respuesta HTTP

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Set-Cookie: token=eyJhbGciOiJSUzI1NiJ9...; Path=/; HttpOnly; Secure; SameSite=Strict
X-Content-Type-Options: nosniff
Strict-Transport-Security: max-age=31536000; includeSubDomains
Content-Length: 831

{"authentication":{"token":"eyJhbGciOiJSUzI1NiJ9...","bid":1,"umail":"user@example.com"}}
  • Línea de estado: versión HTTP + código + descripción.
  • Content-Type: formato del cuerpo de la respuesta.
  • Set-Cookie: instruye al navegador a almacenar una cookie con los atributos indicados.
  • Strict-Transport-Security (HSTS): exige HTTPS en accesos futuros durante el periodo indicado.
  • X-Content-Type-Options: nosniff previene que el navegador «adivine» el tipo MIME.

Métodos HTTP y su relevancia en pentesting

Método Propósito Cuerpo Nota de seguridad
GET Obtener un recurso No Parámetros en URL; se loguean en el servidor
POST Crear / enviar datos Datos en body; no quedan en historial del navegador
PUT Reemplazar recurso completo Si no hay autenticación adecuada → subida arbitraria
PATCH Actualización parcial Mismo riesgo que PUT si mal controlado
DELETE Eliminar recurso No Control de acceso crítico
OPTIONS Métodos disponibles / preflight CORS No Revela métodos permitidos; útil en reconocimiento
HEAD Como GET sin cuerpo No Útil para comprobar existencia de recursos

Códigos de estado clave

Código Significado Relevancia en pentesting
200 OK Éxito Recurso accesible
201 Created Recurso creado Confirma que un POST creó algo
204 No Content Éxito sin cuerpo Común en DELETE exitoso
301/302 Redirección Posible open redirect; 302 roba sesiones si hay cookies sin Secure
400 Bad Request Petición malformada Útil para detectar validaciones
401 Unauthorized Sin autenticación Indica endpoint protegido
403 Forbidden Sin permiso Control de acceso; a veces bypasseable
404 Not Found No existe Diferencia de 403 revela si existe
500 Internal Server Error Error del servidor Puede filtrar rutas o tecnologías
502/503 Gateway / servicio caído Infraestructura detrás del proxy

Cabeceras de seguridad que debes conocer

Como pentester, estas cabeceras te dicen qué tan bien configurado está el servidor:

  • Content-Security-Policy (CSP): define qué orígenes pueden cargar scripts, estilos e imágenes.
    Su ausencia o mala configuración permite XSS. Ejemplo:
    Content-Security-Policy: default-src 'self'; script-src 'self' cdn.example.com
  • Strict-Transport-Security (HSTS): fuerza HTTPS durante el tiempo indicado.
    Strict-Transport-Security: max-age=31536000; includeSubDomains
    Protege contra ataques de degradación SSL.
  • X-Frame-Options: evita que la página se incruste en un <iframe>, previniendo
    clickjacking. MDN la considera obsoleta y recomienda usar en su lugar la directiva CSP
    frame-ancestors; si ambas están presentes, los navegadores que soportan frame-ancestors
    ignoran X-Frame-Options. Aún se incluye a veces de forma redundante para cubrir clientes muy antiguos.
  • X-Content-Type-Options: nosniff — impide que el navegador interprete archivos con MIME distinto
    al declarado (previene ciertos ataques de content sniffing).
  • Location: cabecera de respuesta usada en redirecciones (3xx). Si su valor proviene de input del
    usuario sin validar → open redirect.

2. Cookies y gestión de sesiones

HTTP es sin estado. Para que el servidor recuerde quién eres entre peticiones, usa cookies de sesión.
Cuando haces login, el servidor genera un identificador único (session ID o token JWT) y te lo envía mediante
Set-Cookie. A partir de ese momento, tu navegador incluye automáticamente esa cookie en cada petición
al mismo dominio.

Set-Cookie: sessionId=a3fW9kLp2mX7; Path=/; HttpOnly; Secure; SameSite=Strict; Max-Age=3600

Atributos de seguridad de las cookies

Atributo Qué hace Qué pasa si falta
HttpOnly JavaScript no puede leer la cookie (document.cookie la oculta) Un ataque XSS puede robar el token de sesión
Secure Solo se envía por HTTPS En redes Wi-Fi sin cifrar un atacante captura la cookie en texto claro
SameSite=Strict No se envía en peticiones cross-site (ni desde links externos) Posible CSRF: un sitio malicioso puede hacer peticiones autenticadas en tu nombre
SameSite=Lax Se envía en navegaciones top-level cross-site con métodos seguros (GET/HEAD), pero no en peticiones de recursos cross-site ni en POST cross-site Protección CSRF parcial. Es el valor por defecto de facto en navegadores Chromium y Firefox cuando no se especifica SameSite, pero el comportamiento aún varía entre navegadores, así que conviene declararlo explícitamente
SameSite=None Se envía en todas las peticiones, incluidas las cross-site. Obliga a añadir también el atributo Secure (si no, el navegador rechaza la cookie) Necesario para flujos cross-site legítimos (SSO, iframes de terceros), pero anula la protección CSRF nativa de SameSite
Max-Age / Expires Tiempo de vida de la cookie Sin esto es cookie de sesión (se borra al cerrar el navegador), lo que puede ser un problema o una ventaja
Domain A qué dominios se envía Si es demasiado amplio, se comparte con subdominios potencialmente menos seguros

Como pentester conviene fijarse también en los prefijos de cookie __Secure- y
__Host-. El navegador solo acepta una cookie con prefijo __Secure- si lleva el atributo
Secure y se fijó por HTTPS; y una con prefijo __Host- si además no tiene atributo
Domain y usa Path=/. Su uso es una señal de buena higiene; su ausencia en cookies de
sesión sensibles es un detalle que reportar.

Sesiones vs. tokens (JWT)

En la autenticación basada en sesión, el servidor almacena el estado de sesión en base de datos o
memoria, y la cookie contiene solo el ID. En la autenticación basada en tokens (JWT),
toda la información del usuario se codifica en el token firmado, que viaja en la cookie o en la cabecera
Authorization: Bearer <token>. Ambas aproximaciones tienen ataques específicos que veremos en
módulos posteriores del programa de
certificaciones
.

3. Same-Origin Policy (SOP) y CORS

Same-Origin Policy: el aislamiento del navegador

La Same-Origin Policy es el mecanismo de seguridad más fundamental del navegador web.
Establece que un documento o script cargado desde un origen solo puede leer o modificar recursos
del mismo origen
. Dos URLs tienen el mismo origen si comparten los tres elementos:

Componente Ejemplo base: https://app.ejemplo.com:443
Protocolo https://
Host app.ejemplo.com
Puerto 443

Comparando URLs con la base anterior:

URL ¿Mismo origen? Razón
https://app.ejemplo.com/ruta/otra Solo difiere la ruta
http://app.ejemplo.com No Protocolo diferente
https://app.ejemplo.com:8443 No Puerto diferente
https://api.ejemplo.com No Subdominio diferente

Sin SOP, un script en https://malicioso.com podría acceder al DOM de tu sesión bancaria abierta en
otra pestaña y leer tus datos. La SOP lo impide. Ataques como XSS buscan precisamente ejecutar código en el
origen de la víctima
para saltarse este aislamiento.

CORS: relajar la SOP de forma controlada

CORS (Cross-Origin Resource Sharing) permite al servidor declarar explícitamente qué orígenes
distintos pueden acceder a sus recursos. Lo hace mediante cabeceras HTTP en la respuesta.

Para peticiones complejas (PUT, DELETE, custom headers), el navegador envía antes un
preflight request con el método OPTIONS:

OPTIONS /api/datos HTTP/1.1
Host: api.ejemplo.com
Origin: https://frontend.ejemplo.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type, Authorization
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://frontend.ejemplo.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 86400

Configuraciones CORS peligrosas que verás en pentesting:

  • Access-Control-Allow-Origin: * combinado con
    Access-Control-Allow-Credentials: true — los navegadores modernos lo bloquean, pero indica un
    servidor mal configurado.
  • El servidor refleja el header Origin sin validación:

    // Código vulnerable en el servidor:
    res.header('Access-Control-Allow-Origin', req.headers.origin);
    res.header('Access-Control-Allow-Credentials', 'true');
    

    Esto permite que cualquier dominio controlado por un atacante lea respuestas autenticadas.

Las vulnerabilidades CORS forman parte del
OWASP Top 10
en la categoría A05 (Security Misconfiguration) y A01 (Broken Access Control).

4. TLS/HTTPS: qué protege y qué no

TLS (Transport Layer Security) es el protocolo que convierte HTTP en HTTPS. Actúa entre la capa
de transporte (TCP) y la de aplicación (HTTP). El proceso de negociación (TLS handshake) establece:

  1. La identidad del servidor (certificado X.509 firmado por una CA de confianza).
  2. Un algoritmo de cifrado simétrico acordado entre cliente y servidor (ej. AES-256-GCM).
  3. Claves de sesión efímeras (ECDHE) para que aunque se capture el tráfico, no sea descifrable después.

TLS protege:

  • Confidencialidad del tráfico en tránsito (ni tu ISP ni un atacante en la misma red pueden leer el cuerpo).
  • Integridad: detecta modificaciones del tráfico en tránsito.
  • Autenticación del servidor: certificado firmado por una CA reconocida.

TLS NO protege contra:

  • Vulnerabilidades en la propia aplicación web (SQL injection, XSS, IDOR…).
  • Un atacante que ya tiene acceso al endpoint del servidor.
  • Malware en el cliente que lee memoria o captura pantalla.
  • Errores de implementación (certificados autofirmados sin validación, versiones antiguas TLS 1.0/1.1).

Cuando usamos Burp Suite como proxy, instalamos su certificado CA en el navegador para que el navegador
confíe en Burp. Burp termina el TLS del navegador, inspeccionamos el tráfico en claro, y Burp vuelve a
cifrar la conexión hacia el servidor. Esto es un TLS interception legítimo en laboratorio; en
producción sin autorización sería ilegal.

5. Práctica guiada: Burp Suite Community + OWASP Juice Shop

Qué necesitas

  • Burp Suite Community Edition — descarga gratuita en
    portswigger.net.
  • OWASP Juice Shop — vía Docker (recomendado):

    docker pull bkimminich/juice-shop
    docker run --rm -p 3000:3000 bkimminich/juice-shop
    

    Accede en http://localhost:3000. Documentación oficial:
    owasp.org/www-project-juice-shop.

  • Firefox (recomendado para esta práctica).

Paso 1 — Configurar el proxy de Burp en Firefox

  1. Abre Burp Suite. En la pestaña Proxy > Proxy settings (en versiones actuales ya no se
    llama «Options»), dentro de Proxy listeners verifica que el listener está en
    127.0.0.1:8080 (activo por defecto).
  2. En Firefox: menú ☰ → Preferencias → Configuración de red → selecciona
    Configuración manual del proxy.

    • Proxy HTTP: 127.0.0.1 — Puerto: 8080
    • Activa «Usar este proxy también para HTTPS».
  3. Haz clic en OK.

Paso 2 — Instalar el certificado CA de Burp en Firefox

Sin este paso verás errores SSL al interceptar HTTPS.

  1. Con Firefox apuntando al proxy de Burp, navega a http://burpsuite. Verás la página de Burp.
  2. Haz clic en CA Certificate (esquina superior derecha) y descarga el archivo
    cacert.der.
  3. En Firefox: ☰ → Preferencias → Privacidad y seguridad → Certificados → Ver certificados.
  4. Pestaña AutoridadesImportar → selecciona cacert.der.
  5. Marca «Este certificado puede identificar sitios web» → OK.
  6. Reinicia Firefox.

Paso 3 — Interceptar una petición en Juice Shop

  1. En Burp, ve a Proxy > Intercept y haz clic en Intercept is off para
    activarla (el botón cambiará a Intercept is on).
  2. En Firefox, navega a http://localhost:3000.
  3. Haz clic en el icono de persona (esquina superior derecha) → Login.
  4. Introduce cualquier email y contraseña (ej. test@test.com / 1234) y pulsa
    Log In.
  5. La petición quedará detenida en Burp. Verás algo similar a:
    POST /rest/user/login HTTP/1.1
    Host: localhost:3000
    Content-Type: application/json
    Content-Length: 45
    
    {"email":"test@test.com","password":"1234"}
    
  6. Observa: método POST, ruta /rest/user/login, cuerpo JSON con credenciales en texto claro
    (aquí no hay HTTPS porque es localhost). En un sitio real estarían cifradas por TLS.

Paso 4 — Usar Repeater para reenviar y modificar la petición

  1. Con la petición interceptada, haz clic derecho → Send to Repeater
    (o Ctrl+R).
  2. Pulsa Forward en Intercept para dejar pasar la petición original.
  3. Ve a la pestaña Repeater. Verás la petición en el panel izquierdo.
  4. Modifica el email a admin@juice-sh.op y la contraseña a admin123
    (o prueba diferentes valores).
  5. Pulsa Send.
  6. En el panel derecho, observa la respuesta: código de estado (200, 401…), cabeceras, cuerpo.
    Si el login tiene éxito verás un token JWT en la respuesta.

    HTTP/1.1 200 OK
    Content-Type: application/json; charset=utf-8
    
    {"authentication":{"token":"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...","bid":1,"umail":"admin@juice-sh.op"}}
    
  7. Prueba con credenciales incorrectas. Compara el código de respuesta (401) y el mensaje de error.
    ¿Da el mismo mensaje para usuario inexistente que para contraseña incorrecta?
    Si no — eso es una fuga de información (user enumeration), vulnerable en Bug Bounty.

Paso 5 — Revisar el historial HTTP

Desactiva Intercept (Intercept is off) y navega libremente por Juice Shop. Burp captura
todo en Proxy > HTTP history. Observa:

  • Qué endpoints se llaman al navegar por categorías.
  • Qué cabeceras de seguridad incluye (o no) la respuesta.
  • Si algún endpoint devuelve datos sensibles sin autenticación.

6. Ejercicio propuesto

Con Juice Shop corriendo y Burp configurado, realiza los siguientes pasos por tu cuenta:

  1. Intercepta la petición GET que carga la lista de productos (/rest/products/search?q=).
  2. Envíala a Repeater. Añade comillas simples al final del parámetro q:
    /rest/products/search?q='. ¿Cambia el código de respuesta? ¿Qué dice el cuerpo?
    (Pista: esto es el primer indicio de SQL injection — lo veremos en profundidad en el módulo de SQLi).
  3. Busca en HTTP history una petición que incluya la cabecera Set-Cookie.
    Identifica qué atributos tiene y cuáles faltan.
  4. Usa Proxy > HTTP history, haz clic derecho sobre cualquier petición →
    Send to Intruder y explora la interfaz (no lances ataques aún).

Errores comunes y cómo evitarlos

«Burp intercepta pero Firefox muestra error SSL»

El certificado CA de Burp no está instalado correctamente en Firefox, o reinstalaste Burp (cada instalación
genera un CA nuevo). Repite el Paso 2. Asegúrate de importar el archivo que descarga Burp desde
http://burpsuite (cacert.der, en formato DER) en la pestaña Autoridades,
y de marcar la casilla «Este certificado puede identificar sitios web». Recuerda que Firefox mantiene su propio
almacén de certificados, independiente del de Windows.

«Firefox no carga nada cuando activo el proxy»

Comprueba que el listener de Burp está activo: Proxy > Proxy settings → en Proxy listeners, el listener
127.0.0.1:8080 debe figurar como activo (running). También ocurre si Intercept está activo y no haces Forward:
la petición queda esperando. Pulsa Forward o desactiva Intercept.

«Juice Shop no responde después de Docker run»

Docker puede tardar 30-60 segundos en inicializar la aplicación Node.js. Espera y recarga
http://localhost:3000. Si el error persiste, comprueba que el puerto 3000 no está ocupado:
docker ps muestra los contenedores activos y los puertos mapeados.

FAQ

¿Cuál es la diferencia entre HTTP/1.1 y HTTP/2 para el pentesting?

HTTP/2 multiplexa múltiples peticiones sobre una sola conexión TCP y usa compresión de cabeceras (HPACK).
Burp Suite maneja HTTP/2 transparentemente y lo muestra en formato HTTP/1.1 en la interfaz para facilitar
la lectura. Para el pentesting de aplicaciones web, la diferencia práctica es mínima; las vulnerabilidades
de lógica de aplicación aplican igual en ambas versiones.

¿Por qué los tokens JWT viajan a veces en cookies y a veces en cabeceras?

Depende del diseño de la aplicación. Cuando viajan en la cabecera Authorization: Bearer <token>,
el JavaScript del frontend los gestiona (localStorage), lo que los expone a XSS si no hay protección adecuada.
Cuando viajan en cookies con HttpOnly, el JavaScript no puede leerlos, pero son vulnerables a CSRF
si no se implementa SameSite o un token anti-CSRF. Ninguna opción es perfecta por sí sola.

¿Necesito Burp Suite Pro para este curso?

No. Todos los ejercicios de este módulo y los siguientes se pueden realizar con la edición
Community gratuita. Las limitaciones principales de Community son la velocidad reducida
de Intruder (suficiente para aprender) y la ausencia del escáner activo automático. Para la certificación
eJPT y los niveles básico-intermedio de Bug Bounty, Community es más que suficiente.
Consulta la ruta completa en cursos y
certificaciones
.

¿Qué diferencia hay entre intercept y HTTP history en Burp?

Intercept detiene cada petición y espera tu acción (Forward, Drop, modificar). Es útil para
manipular peticiones en tiempo real. HTTP history registra todo el tráfico de forma pasiva
sin interrumpirlo. Para una primera exploración de la aplicación, trabaja con Intercept desactivado y luego
analiza el historial para encontrar endpoints interesantes.

Recordatorio ético final

Todo lo que has aprendido en este módulo —interceptar tráfico, modificar peticiones, analizar cookies— es legal
y legítimo únicamente en entornos propios o autorizados. Juice Shop existe precisamente para
esto. Antes de practicar contra cualquier sistema real, obtén permiso por escrito.
El hacking ético sin autorización no existe: se llama delito. Más información sobre el marco legal y
certificaciones profesionales en nuestra
guía completa de hacking web
.