Saltar al contenido
Curso Desarrollo seguro con IA en Laravel
06/22 Fallos típicos del código generado por IA Autorización en el código generado por IA: la policy que existe y no se llama
Tu lectura Quedan 14 min
Lección 6 de 22 · Fallos típicos del código generado por IA

Autorización en el código generado por IA: la policy que existe y no se llama

14 min de lectura Laravel 13

Hola, bienvenido. En esta lección vamos a corregir el fallo de autorización de invoices. InvoicePolicy existe, Laravel la descubre sola y los métodos que editan y borran facturas la llaman, pero el detalle de una factura y la descarga de su adjunto no. Así que cualquier usuario con sesión que tenga la URL de una factura de otro la ve entera y se descarga su adjunto. Vamos a escribir el test que lo demuestra, a añadir la llamada a la policy en los 2 sitios y a dejar el test en composer qa.

Fíjate en que es una omisión, el tipo de fallo más frecuente en el código de los agentes, como vimos en la lección 1. Todas las líneas que escribió el agente están bien, y por eso al revisar no salta nada a la vista.

Qué comprueba cada acción de facturas

Partimos de invoices tal como lo dejamos en la lección anterior. Si recorremos InvoiceController y el controlador de la descarga, cada acción comprueba a su manera que la factura es del usuario, salvo 2:

Acción Cómo comprueba de quién es la factura
index Solo lista $request->user()->invoices()
create y store Solo ofrece y acepta clientes del usuario, con Rule::exists filtrado por user_id
show No lo comprueba
edit Gate::authorize('update', $invoice)
update El authorize() de UpdateInvoiceRequest, con la misma policy
destroy Gate::authorize('delete', $invoice)
Descarga del adjunto No lo comprueba

¿Cómo se llega a esto con un agente que ha escrito la policy él mismo? Si miras el plan de la lección 3, la policy aparece al final de la tarea de las facturas, en la misma línea que el listado, el detalle, la edición y el borrado, sin decir dónde hay que llamarla. show solo tiene que enseñar una factura, y la enseña. La descarga fue otra tarea del plan, "Adjunto de la factura en el disco local y descarga con InvoiceAttachmentController", y en esa tarea nadie habló de autorización. El resultado funciona y los tests pasan.

Con los tests pasa lo que vimos en la lección 1. Fíjate en el último test de InvoiceTest: comprueba que otro usuario no puede editar ni borrar una factura ajena, y no dice nada de verla. El agente escribió tests de lo que la aplicación hace y de lo que él protegió, así que lo que no protegió tampoco tiene test.

Este fallo tiene nombre: IDOR, referencia directa insegura a un objeto (Insecure Direct Object Reference). OWASP lo define como la vulnerabilidad que aparece cuando se puede acceder a un objeto cambiando el identificador que viaja en la URL o en los parámetros, porque la aplicación no comprueba si ese objeto es de quien lo pide. El OWASP Top 10:2025 lo incluye en A01, Broken Access Control. En invoices el identificador es el id de /invoices/{invoice}, y el route model binding de Laravel busca la factura entre todas las de la tabla, no entre las del usuario. La propia hoja de OWASP sobre IDOR avisa de que cambiar los ids por identificadores difíciles de adivinar, como un UUID, es una capa más y nunca sustituye a la comprobación de acceso.

En la lección 1 vimos la nota de la AEPD del 14 de septiembre de 2026, en la que un agente hizo un login correcto y, una vez dentro, buscó vulnerabilidades en la aplicación hasta acceder a facturas. La nota no dice qué vulnerabilidad encontró, pero el punto de partida es el mismo que el de este fallo: alguien que ya tiene sesión en la aplicación.

En esta lección nos quedamos con la forma más habitual en el código de un agente: una llamada a la policy que nadie escribió. Si lo que necesitas es un sistema de roles y permisos completo, lo tienes en Sistema de Roles y Permisos Personalizado con Laravel 12 (se abre en una pestaña nueva).

Lo que queda de esta lección
  1. 02El test: la factura de otro usuario devuelve 403
  2. 03La solución: llamar a la policy en show y en la descarga
  3. 04El test se queda en composer qa
Sigue leyendo con tu suscripción El curso completo, con el certificado y el foro con los planes trimestral y anual, está incluido en la suscripción. Ver los planes