Desarrollo

Por qué poner un UUID en una URL es un compromiso

Un identificador aleatorio oculta cuántos registros tienes e impide recorrerlos contando. También vuelve toda URL ilegible e imposible de dictar, y no es control de acceso.

Tres cajas con números consecutivos, la del medio rellena y con chevrones entre ellas, junto a los cinco grupos apilados de un UUID sin vecino al que pasar.

Un UUID en una URL impide que alguien cambie /orders/1041 por /orders/1042 para ver el registro siguiente, y oculta cuántos registros tienes. No impide que quien ya tiene el enlace lo comparta, ni reemplaza comprobar quién puede ver la página. Lo que pagas por él es una URL que nadie puede leer en voz alta, un identificador que no se ordena y un índice de más o menos el doble de ancho. Si vale la pena depende de qué proteja la URL.

¿Qué protege realmente un UUID en una URL?

Un id secuencial filtra dos cosas. La primera es la cantidad: te registras, te toca el usuario 48213 y ya sabes más o menos qué tan grande es el servicio. Vuelves a mirar una semana después y sabes a qué ritmo crece. La segunda son los vecinos: si /invoices/1041 es tuyo, /invoices/1042 es de otra persona, e intentarlo no cuesta nada.

El segundo problema solo es una vulnerabilidad cuando el servidor entrega el registro sin preguntar si tú puedes verlo. Esa falla tiene nombre, referencia directa insegura a objetos (insecure direct object reference), y pertenece a la familia más amplia del control de acceso roto. Un identificador aleatorio no la elimina. La vuelve mucho más difícil de explotar, porque un UUID v4 lleva 122 bits aleatorios y nadie va a adivinar el siguiente. Cómo se distribuyen esos bits en v4 y v7 importa acá, porque un v7 además dice cuándo se creó el registro.

Así que la afirmación exacta es modesta: un id aleatorio vuelve impracticable la enumeración y oculta tu tamaño. El arreglo del error de fondo sigue siendo una comprobación de permisos en cada petición.

¿Qué no protege?

Un enlace no listado es una buena elección cuando "cualquiera con el enlace" es justamente la intención, como en un documento compartido. Es la elección equivocada para datos privados, donde la página debería comprobar una sesión sin importar cómo se vea la URL.

¿Qué cuesta?

Si igual te quedas con UUID, el generador de UUID puede quitar los guiones para una forma de 32 caracteres. Es más corta de copiar, pero sigue sin ser algo que una persona pueda dictar, y la forma en minúsculas con guiones sigue siendo la que conviene guardar.

¿Cuándo es mejor un id secuencial?

Cuando el registro es público de todos modos. Los números de artículo, los números de ticket que los usuarios te citan y los números de factura no ganan nada con esconderse, y ganan mucho con ser legibles. Además, muchos regímenes tributarios esperan que los números de factura sigan una secuencia sin huecos, así que revisa el tuyo antes de reemplazarlos por cadenas aleatorias.

También funciona cuando el acceso se comprueba bien en el servidor, porque entonces un vecino adivinado devuelve un rechazo y no un registro. La fuga que queda es la cantidad, que solo importa si tu volumen es algo que preferirías mantener en privado.

¿Cuáles son las opciones intermedias?

Un atajo que conviene evitar: las bibliotecas que codifican un entero en una cadena de aspecto aleatorio. Son ofuscación reversible, no un secreto, así que trátalas como algo cosmético.

¿Puede una herramienta decirme si mis URL son seguras?

No, y conviene ser claro con eso. El generador de UUID crea identificadores v4 o v7 en tu navegador y su inspector lee la versión y, en un v7, la hora de creación a partir de los bits. No puede ver tu servidor, así que no puede decirte si un endpoint comprueba la propiedad del registro, si una página de listado filtra los ids o si tu fuente de aleatoriedad es sólida. Esa comprobación es una prueba que haces contra tu propia aplicación, con la sesión de un usuario, pidiendo el registro de otro.

Si estás sopesando un id aleatorio contra un contador, el generador de UUID hace los dos tipos de a mil por vez para que veas qué tan largo queda el resultado en una ruta real antes de decidirte. Corre en tu navegador y nada de lo que generes se envía a ningún lado.

Y si lo que en el fondo quieres es un enlace que solo una persona debería abrir, cómo enviarle una contraseña a alguien de forma segura explica la diferencia entre un enlace imposible de adivinar y un secreto entregado como corresponde.

Preguntas frecuentes

¿Es seguro poner un UUID en una URL?

Es seguro frente a que lo adivinen: un UUID v4 tiene 122 bits aleatorios, así que nadie puede recorrer tus registros cambiando el id. No es seguro como sustituto de un login, porque cualquiera que tenga la URL puede abrirla, y las URL se filtran por logs, historial y cabeceras Referer. Comprueba los permisos en el servidor sin importar cómo se vea el id.

¿Debo usar ids secuenciales o UUID en las URL?

Usa ids secuenciales cuando el registro es público o la gente necesita citarlo, y el acceso se comprueba igual en el servidor. Usa ids aleatorios cuando la cantidad de registros es algo que quieres mantener en privado, o cuando un permiso omitido expondría los registros vecinos. Muchos sistemas conservan los dos: un entero dentro de la base de datos y un id público aleatorio en la URL.

¿Un UUID evita los errores de referencia directa insegura a objetos?

No. Los vuelve mucho más difíciles de explotar, porque un atacante no puede adivinar el id de otro registro, pero el error es una comprobación de permisos ausente y sigue ahí. Si un UUID se filtra por una página de listado, un correo o una captura compartida, el registro queda abierto para quien lo encuentre.

¿Por qué los UUID son malos para URL legibles?

Un UUID son 36 caracteres de hexadecimal y guiones que nadie puede leer en voz alta, recordar ni comparar de un vistazo. Un cliente que lo cite por teléfono va a equivocarse. Si las personas necesitan referirse al registro, dale un número corto pensado para humanos o un slug legible junto al UUID.

¿Qué largo necesita un id aleatorio en una URL?

Suficiente para que adivinar a ciegas no tenga esperanza, dada la cantidad de intentos que permitas. Diez caracteres de un alfabeto de 32 símbolos son 50 bits, más o menos un acierto cada mil millones de intentos contra un millón de registros. Eso vale solo si limitas la frecuencia de las peticiones, y no dice nada sobre quién puede ver la página.

Última actualización 28 de septiembre de 2026