1.2 – [Herramientas] – Postman

En el mundo real —y en el mundo OWASP— el fallo más común no suele ser una inyección digna de Hollywood, sino algo mucho más mundano: el control de acceso mal aplicado. El punto 1 del OWASP Top 10, conocido como A01: Broken Access Control, lleva años liderando el ranking porque rompe la promesa básica de cualquier sistema: cada usuario solo puede hacer lo que le toca.

Aquí es donde entra Postman, una herramienta que, usada con mentalidad de auditor, se convierte en una lupa perfecta para detectar accesos indebidos, IDORs y permisos mal definidos… sin necesidad de levantar un laboratorio complejo.

Para en Windows, Mac y Linux. Puedes descargarlo aquí:

https://www.postman.com/downloads


Para OWASP A01 en una frase clara

Broken Access Control ocurre cuando una aplicación no verifica correctamente quién eres y qué puedes hacer, permitiendo acciones como:

  • Acceder a recursos de otros usuarios.
  • Ejecutar funciones administrativas sin ser admin.
  • Modificar datos que deberían ser de solo lectura.
  • Saltarse flujos lógicos del backend.

No es magia negra. Es lógica mal aplicada.


Por qué Postman es ideal para auditar A01

Postman no es solo “un cliente para hacer peticiones”. Es una consola de pruebas controladas donde puedes:

  • Repetir peticiones exactas.
  • Cambiar headers, tokens y parámetros a voluntad.
  • Simular distintos usuarios sin cambiar de sesión real.
  • Comparar respuestas del backend sin pasar por el frontend.

En seguridad, quitar el frontend es quitar el maquillaje. Lo que queda es la verdad del backend.


Caso práctico mental: el backend desnudo

Imagina una API típica:

GET /api/pedidos/123
Authorization: Bearer TOKEN_USUARIO

Con Postman puedes:

  • Cambiar el 123 por otro ID.
  • Reutilizar el mismo token.
  • Ver si el servidor comprueba la propiedad del recurso o solo confía en el ID.

Si responde con datos que no son tuyos, no hay debate: A01 confirmado.


Qué pruebas de Broken Access Control se hacen con Postman

1. IDOR (Insecure Direct Object Reference)

Cambias identificadores (id, user_id, order_id) y observas:

  • ¿Devuelve datos?
  • ¿Devuelve error 403?
  • ¿Devuelve “no encontrado” solo cuando conviene?

Un backend sano no distingue entre “no existe” y “no es tuyo”.


2. Escalada horizontal

Mismo rol, distinto usuario.

Ejemplo:

  • Usuario A accede a /api/profile/45
  • Usuario B prueba /api/profile/45

Si ambos ven lo mismo, el sistema cree que “autenticado” es suficiente. Spoiler: no lo es.


3. Escalada vertical

Pruebas endpoints de administrador con un token normal:

POST /api/admin/users

Si la respuesta no es un 403 inmediato, hay un problema estructural, no un bug puntual.


4. Métodos HTTP olvidados

Con Postman puedes cambiar el verbo en segundos:

  • GETPUT
  • PUTDELETE

Muchos sistemas protegen la vista, pero no la acción. El backend acepta lo que el frontend jamás envía.


5. Falta de control en acciones lógicas

No todo es CRUD. Prueba acciones como:

  • “cerrar pedido”
  • “aprobar solicitud”
  • “finalizar reserva”

Si el backend no valida el estado previo y el rol, Postman lo descubre rápido.


Postman como herramienta docente (y no solo ofensiva)

Aquí viene la parte elegante: Postman no solo sirve para atacar, sino para enseñar a pensar bien.

En clase o laboratorio, permite que el alumnado:

  • Vea la diferencia entre autenticación y autorización.
  • Entienda por qué el control debe estar en el backend.
  • Aprenda a documentar evidencias claras (request + response).
  • Desarrolle mentalidad de auditor: observar, probar, registrar.

La seguridad no va de romper cosas, va de demostrar por qué se rompen.


Buenas prácticas que Postman ayuda a verificar

Un backend bien diseñado debería:

  • Validar permisos en cada endpoint, no en el frontend.
  • No confiar en IDs enviados por el cliente.
  • Aplicar roles y ownership en lógica de servidor.
  • Responder con errores coherentes (403 > 401 > 404).

Postman no arregla estos problemas, pero los deja al descubierto con brutal honestidad.


Conclusión: el bisturí del A01

Postman es a Broken Access Control lo que un bisturí es a la anatomía:
no grita, no hace ruido, pero corta justo donde duele.

Usado con ética y método, es una de las mejores herramientas para entender por qué A01 sigue siendo el rey del OWASP Top 10 y por qué el control de acceso no es una opción, sino la base de todo sistema seguro.


Proyecto guiado: “Postman vs. OWASP A01 – Auditoría de Control de Acceso en un CRUD con sesión”

Usar Postman para auditar un CRUD con autenticación (sesión) y detectar fallos típicos de Broken Access Control:

  • IDOR: acceder/modificar recursos de otros.
  • Escalada horizontal: mismo rol, otro usuario.
  • Escalada vertical: endpoints “admin” accesibles sin serlo.
  • Métodos HTTP y acciones no previstas por el frontend.
  • Validación de ownership (propiedad del recurso) en el backend.

Resultados

  1. Colección de Postman con:
  • requests organizadas por carpetas,
  • variables de entorno,
  • tests automáticos básicos.
  1. Informe de auditoría (capturas + evidencias):
  • Request y response (código, body relevante),
  • Resultado esperado vs. real,
  • Conclusión: “OK” o “Vulnerable” + impacto.

Requisitos

  • Una con un CRUD funcionando en Apache.
  • Dos usuarios reales en la app:
    • userA (normal)
    • userB (normal)
    • Opcional: admin (si existe rol)
  • Cada usuario debe tener al menos 2 registros creados en el CRUD (por ejemplo “posts”, “productos”, “reservas”, etc.).

Reglas de seguridad (muy importante)

  • Solo probar contra el entorno del aula/lab, no producción.
  • No borrar datos de otros equipos/grupos.
  • Si se detecta un fallo, se documenta: no se explota.

1) Instalar y preparar Postman

  1. Instala Postman (desktop).
  2. Crea un Workspace: OWASP-A01-Auditoria-CRUD.
  3. Crea un Environment: LAB-CRUD.
  4. Añade estas variables:
  • baseUrl = http://IP_O_DOMINIO_DEL_SERVIDOR
  • usernameA = userA
  • passwordA = ...
  • usernameB = userB
  • passwordB = ...
  • cookieA = (vacío)
  • cookieB = (vacío)
  • idA_1 = (vacío)
  • idB_1 = (vacío)

Nota: vamos a guardar cookies de sesión para simular usuarios distintos.


2) Descubrir endpoints reales (sin adivinar)

Aquí no inventamos rutas: las sacamos del propio sistema.

2.1 Identificar la request de login

  1. En el navegador, abre DevTools → Network.
  2. Inicia sesión como userA.
  3. Busca la request de login y apunta:
    • Método (POST/GET)
    • URL exacta
    • Tipo de datos (form-data, x-www-form-urlencoded, JSON)
    • Respuesta (¿redirige? ¿devuelve JSON? ¿set-cookie?)

Ejemplo típico (orientativo):

  • POST /login.php
  • body: username=...&password=...
  • response: Set-Cookie: PHPSESSID=...

2.2 Identificar endpoints del CRUD

Repite en Network mientras haces:

  • listar
  • ver detalle
  • crear
  • editar
  • borrar

Apunta URLs y parámetros.


Vamos a hacer dos flujos de login (usuario A y usuario B) y guardar sus cookies.

3.1 Carpeta “Auth”

Crea una colección: A01 - CRUD Audit.
Dentro crea carpeta 01_AUTH.

Request: Login - UserA

  • Método/URL: el del sistema (ej: POST {{baseUrl}}/login.php)
  • Body: los campos reales

En Tests, añade:

// Guarda cookie de sesión (si el backend usa cookies)
const cookie = pm.response.headers.get('Set-Cookie');
if (cookie) {
  pm.environment.set('cookieA', cookie.split(';')[0]); // PHPSESSID=...
}
pm.test("Login UserA devuelve 200/302", function () {
  pm.expect([200,302]).to.include(pm.response.code);
});

Request: Login - UserB

Igual, pero guardando cookieB:

const cookie = pm.response.headers.get('Set-Cookie');
if (cookie) {
  pm.environment.set('cookieB', cookie.split(';')[0]);
}
pm.test("Login UserB devuelve 200/302", function () {
  pm.expect([200,302]).to.include(pm.response.code);
});

Si tu app no devuelve Set-Cookie en login porque ya lo setea antes, Postman igual puede mantener cookies con su “Cookie Jar”. Pero para enseñar A01, guardar cookie en variable hace que el alumno entienda qué está pasando.


4) Preparar “headers por usuario” (simular identidad)

En cada request del CRUD, pon el header:

  • Para simular UserA:
    • Cookie: {{cookieA}}
  • Para simular UserB:
    • Cookie: {{cookieB}}

Crea dos carpetas:

  • 02_CRUD_UserA
  • 03_CRUD_UserB

Y duplica requests para cada usuario (sí, duplicar aquí ayuda a aprender).


5) Paso clave: obtener IDs reales de cada usuario

Necesitamos un ID de un recurso de A y otro de B para probar IDOR.

5.1 Listar recursos como UserA

Request: List - UserA

  • GET {{baseUrl}}/ruta_listado (la real)

En Tests, intenta extraer un id del JSON/HTML.

  • Si la API devuelve JSON (ideal):
const data = pm.response.json();
pm.environment.set("idA_1", data[0].id);
pm.test("Tengo idA_1", () => pm.expect(pm.environment.get("idA_1")).to.not.be.undefined);
  • Si devuelve HTML, el alumno puede copiar el ID manualmente del listado o detalle y ponerlo en idA_1.

5.2 Repetir con UserB

Request: List - UserB y guardar/copiar idB_1.


6) Pruebas OWASP A01 con Postman (con ejemplos)

Ahora viene el núcleo. Cada prueba tiene:

  • Qué se prueba
  • Cómo hacerlo en Postman
  • Qué sería correcto
  • Qué sería vulnerable

6.1 IDOR de lectura (Broken Access Control)

Prueba

UserA intenta ver el recurso de UserB.

Request (como UserA):

GET {{baseUrl}}/recurso/{{idB_1}}
Header:

  • Cookie: {{cookieA}}

Resultado correcto

  • 403 Forbidden o un error equivalente (o 404 “no existe”).
  • Nunca debería devolver el contenido del recurso de B.

Vulnerable

  • Devuelve 200 y muestra el recurso de B.

📌 Evidencia en informe:

  • URL + cookieA + response.

6.2 IDOR de modificación (PUT/POST/EDIT)

Prueba

UserA intenta editar el recurso de B.

Ejemplo (orientativo):

  • POST {{baseUrl}}/recurso/edit.php?id={{idB_1}}
    o
  • PUT {{baseUrl}}/api/recurso/{{idB_1}}

Body: cambia un campo (ej. title=HACKED_BY_A).

Resultado correcto

  • 403 / error.
  • El recurso no cambia.

Vulnerable

  • 200 / “ok” y el recurso de B aparece modificado.

📌 Extra didáctico:

  • Tras editar, hacer GET del recurso y comprobar si cambió.

6.3 IDOR de borrado (DELETE)

Prueba

UserA intenta borrar el recurso de B.

Ejemplo:

  • DELETE {{baseUrl}}/api/recurso/{{idB_1}}
    o
  • POST {{baseUrl}}/recurso/delete.php?id={{idB_1}}

Resultado correcto

  • 403 / no permitido.

Vulnerable

  • Recurso eliminado.

⚠️ En clase:

  • Hazlo en un “registro señuelo” para no romper trabajos.

6.4 Escalada vertical (usuario normal llama a admin)

Si existe panel admin:

  • GET {{baseUrl}}/admin/users
  • POST {{baseUrl}}/admin/create-user

Como UserA (cookieA).

Correcto: 403.
Vulnerable: 200.

Si no existe admin en su app, crea un endpoint “solo admin” ficticio en el enunciado como extensión (pero aquí trabajamos con lo real).


6.5 Fallo por confiar en parámetros (user_id)

Muchos CRUD hacen esto:

  • POST /recurso/create con user_id=...

Prueba

UserA crea un recurso pero forzando user_id={{idDeB}} o similar.

Correcto:

  • El backend ignora ese user_id y asigna el de la sesión.
    Vulnerable:
  • Se puede crear contenido “a nombre de otro”.

7) Tests automáticos en Postman (mini “cinturón de seguridad”)

En cada request de prueba A01 añade tests como:

pm.test("No debería permitir acceso indebido", function () {
  pm.expect([401,403,404]).to.include(pm.response.code);
});

Y en las que sean “normales” (acceso legítimo):

pm.test("Acceso legítimo OK", function () {
  pm.expect(pm.response.code).to.eql(200);
});

Esto enseña a pensar como QA + seguridad: expectativas claras.


8) Estructura de la colección (lista final)

Colección A01 - CRUD Audit:

  • 01_AUTH
    • Login UserA
    • Login UserB
  • 02_CRUD_UserA
    • List A
    • View A (idA_1)
    • View B (idB_1) IDOR read test
    • Edit B (idB_1) IDOR write test
    • Delete B (idB_1) IDOR delete test
  • 03_CRUD_UserB
    • (equivalentes)
  • 04_A01_REPORT_EVIDENCES
    • Requests “limpios” que sirvan de referencia para el informe

9) Guion de un informe

Cada hallazgo debe tener:

  • Título: “IDOR lectura en /recurso/{id}”
  • Usuario atacante: UserA
  • Recurso víctima: idB_1
  • Pasos (Postman): request exacta + headers
  • Resultado esperado: 403/404
  • Resultado real: 200 con datos
  • Impacto: acceso a datos de terceros / modificación / borrado
  • Recomendación:
    • Verificar ownership en backend
    • Reglas RBAC/ABAC
    • No confiar en IDs del cliente
    • Tests de autorización por endpoint