Introducción
Una factura registra lo que compró un cliente, el precio y su dirección de facturación. Cada cliente debe poder leer sus propias facturas o las que se le hayan compartido explícitamente. Conocer un ID no otorga permiso para leerlo.
Tienes autorización para probar Invoice Desk con datos sintéticos como Alex. Empieza por el acceso normal, compara una factura compartida con una privada y guarda la respuesta privada para demostrar un fallo en el límite de propiedad. El laboratorio termina con la validación; no repararás el servidor. Solo están autorizados los objetos proporcionados.
Establecer tu acceso normal
Selecciona la pestaña Invoice Desk en la interfaz del laboratorio para comenzar este paso.
En este paso, inicia sesión como Alex y obtén tu propia factura antes de probar otra cuenta.
Cambia a la pestaña Invoice Desk. El diagrama muestra un cliente, que envía solicitudes, y un servidor de API, que responde. Una API es la interfaz de solicitudes de la aplicación. API: ready procede de una consulta real de salud. La tabla indica las reglas previstas:
| ID de factura | Propietario | Compartida con | ¿Alex puede leerla? |
|---|---|---|---|
inv-104 |
alex |
Nadie | Sí: propietario |
inv-208 |
morgan |
Nadie | No: privada |
inv-315 |
riley |
alex |
Sí: uso compartido explícito |
En el portal introduce usuario alex y contraseña shop-alex-42; pulsa Sign in. Debe aparecer Signed in as alex. Introduce inv-104 en Invoice ID y pulsa View invoice. El campo owner debe ser alex.

Cambia a la pestaña Client Terminal. Es un espacio de cliente aislado en /home/student/project, no el servidor. invoice-api:8000 identifica al servidor dentro de esta red de práctica, no a un destino público. curl envía solicitudes HTTP desde el terminal. HTTP es el protocolo de solicitud/respuesta utilizado aquí; GET pide leer un recurso. La ruta posterior a la dirección identifica ese recurso. -i incluye el estado y las cabeceras de respuesta.
Sin sesión, espera 401 Unauthorized: debes iniciar sesión.
Cambia a la pestaña Client Terminal antes de ejecutar el siguiente comando.
curl -i http://invoice-api:8000/api/invoices/inv-104
Iniciar sesión en el navegador no inicia sesión en curl. Una sesión es el registro del servidor sobre quién inició sesión; una cookie aleatoria relaciona las solicitudes posteriores con ese registro. El comando siguiente envía un objeto JSON, un formato con campos nombrados. -H establece una cabecera que indica JSON, -d envía credenciales y selecciona POST, y -c guarda la cookie devuelta en session.txt. Las comillas simples mantienen los espacios y las comillas dobles juntos como un único argumento de shell.
curl -sS -c session.txt -H 'Content-Type: application/json' -d '{"username":"alex","password":"shop-alex-42"}' http://invoice-api:8000/api/login
-sS oculta el progreso pero muestra errores de conexión. account debe ser alex. -b envía la cookie guardada. Comprueba la identidad de la sesión:
curl -sS -b session.txt http://invoice-api:8000/api/me
Solicita tu factura:
curl -sS -b session.txt http://invoice-api:8000/api/invoices/inv-104
Lee invoice_id, owner, item y total_usd: Alex compró Desk lamp por 38.00. La lista vacía shared_with, [], significa que nadie más recibió permiso. Este comportamiento es normal. La comprobación usa la respuesta real del servidor a Alex, tanto desde el terminal como desde el portal.
Si recibes 401 después del inicio de sesión, repite el comando de login en este terminal y vuelve a probar con -b session.txt. Un error de conexión significa que no recibiste una respuesta HTTP; revisa la dirección y API: ready.
Solicitar otra factura
Selecciona la pestaña Client Terminal en la interfaz del laboratorio para comenzar este paso.
En este paso, compara el uso compartido explícito con una factura privada manteniendo la misma identidad.
La autenticación responde «¿Quién eres?». La autorización responde «¿Puede esta persona leer esta factura?». Un inicio de sesión correcto solo resuelve lo primero. Descarga primero la factura compartida legítimamente. Una descarga sigue siendo GET; /download selecciona una respuesta para guardar, con los mismos campos JSON.
Cambia a la pestaña Client Terminal antes de ejecutar el siguiente comando.
curl -sS -b session.txt http://invoice-api:8000/api/invoices/inv-315/download
El propietario es riley, pero shared_with contiene alex. Este acceso está permitido. Un propietario diferente no demuestra por sí solo un fallo.
Predice el caso privado: inv-208 pertenece a Morgan y no se comparte con nadie; Alex debería recibir una denegación, normalmente 403 Forbidden. Un servicio también puede usar 404 Not Found para ocultar que existe un objeto privado. Aquí 404 también indica un ID desconocido. 200 OK significa que la solicitud tuvo éxito; el cuerpo muestra qué se expuso.
-v muestra la solicitud enviada y las cabeceras recibidas. También muestra la cookie de la sesión de práctica; no compartas su salida fuera del laboratorio. Ejecuta:
curl -v -b session.txt http://invoice-api:8000/api/invoices/inv-208
Localiza GET /api/invoices/inv-208 y HTTP/1.0 200 OK. El cuerpo muestra propietario morgan, lista de uso compartido vacía, Studio microphone y dirección 82 Cedar Lane. El servidor entregó un objeto privado a Alex. Cambiaste la ruta del objeto, no la identidad de sesión. Los ID predecibles facilitaron la prueba; la ausencia del control de permisos causó la exposición.
Cambia a la pestaña Invoice Desk para repetir ambas solicitudes: Download invoice para inv-315 y View invoice para inv-208. El cliente web guarda las descargas en el mismo espacio de trabajo. La comprobación requiere la descarga compartida permitida y la vista privada, no un archivo explicativo.

Verificar la exposición
Selecciona la pestaña Client Terminal en la interfaz del laboratorio para comenzar este paso.
En este paso, conserva la descarga privada real y relaciona los datos expuestos con su impacto comercial.
Usa /download para la factura privada. -o escribe los bytes de respuesta en un archivo en lugar de mostrarlos. Guarda la respuesta completa como private-invoice.json en el espacio de cliente actual:
Cambia a la pestaña Client Terminal antes de ejecutar el siguiente comando.
curl -sS -b session.txt -o private-invoice.json http://invoice-api:8000/api/invoices/inv-208/download
cat muestra un archivo para leerlo:
cat private-invoice.json
Debe ser la misma factura de Morgan: invoice_id inv-208, propietario morgan, importe 129.00 y dirección de facturación. Si guardaste un error 401 o la factura compartida, inicia sesión otra vez si hace falta y descarga la privada designada; -o reemplaza el archivo.
Como alternativa, cambia a la pestaña Invoice Desk. Con la sesión de Alex iniciada, introduce inv-208 y pulsa Download invoice. Este cliente web reenvía la solicitud real a la API y guarda la respuesta sin modificar en /home/student/project/private-invoice.json; puedes leerla después de volver a la pestaña Client Terminal. Ambos métodos cumplen el mismo resultado.
Ejecuta la comprobación. Compara los bytes guardados con la factura designada y comprueba que el servidor registró esa descarga bajo la sesión de Alex. Una afirmación copiada, una factura inventada, una compartida permitida o un archivo sin descarga de cliente coincidente no demuestran el resultado.
El impacto es la divulgación de compras y dirección de otro cliente. El servidor debe comprobar propiedad o permiso explícito de uso compartido para cada objeto solicitado, incluidas las descargas. Ocultar enlaces o dificultar la adivinación de ID no sustituye ese control. Es el problema de autorización de objetos descrito por OWASP BOLA. Tu prueba autorizada ha terminado; la reparación corresponde a otra tarea.
Resumen
Creaste una sesión de cliente, leíste tu factura, distinguiste uso compartido explícito de acceso privado y guardaste una respuesta real entre cuentas. Verificaste los datos expuestos y la identidad que los recibió, sin acceso al servidor ni credenciales de la víctima.



