Desenvolvimento

Por que colocar um UUID numa URL é uma troca

Um identificador aleatório esconde quantos registros você tem e impede que alguém os percorra contando. Ele também deixa toda URL ilegível e impossível de ditar, e não é controle de acesso.

Três caixas com números consecutivos, a do meio preenchida e com setas entre elas, ao lado dos cinco grupos empilhados de um UUID sem vizinho para onde ir.

Um UUID numa URL impede que alguém troque /orders/1041 por /orders/1042 para ver o registro seguinte, e esconde quantos registros você tem. Ele não impede que quem já tem o link o compartilhe, nem substitui verificar quem pode ver a página. O que você paga por ele é uma URL que ninguém consegue ler em voz alta, um identificador que não ordena e um índice de mais ou menos o dobro da largura. Se compensa depende do que a URL protege.

O que um UUID numa URL realmente protege?

Um id sequencial vaza duas coisas. A primeira é a quantidade: você se cadastra, recebe o usuário 48213 e já sabe mais ou menos o tamanho do serviço. Olhe de novo uma semana depois e você sabe o ritmo de crescimento. A segunda são os vizinhos: se /invoices/1041 é seu, /invoices/1042 é de outra pessoa, e tentar não custa nada.

O segundo problema só é uma vulnerabilidade quando o servidor entrega o registro sem perguntar se você pode vê-lo. Essa falha tem nome, referência direta insegura a objetos (insecure direct object reference), e pertence à família mais ampla do controle de acesso quebrado. Um identificador aleatório não a elimina. Ele a torna muito mais difícil de explorar, porque um UUID v4 carrega 122 bits aleatórios e ninguém vai adivinhar o próximo. Como esses bits se distribuem no v4 e no v7 importa aqui, porque um v7 também diz quando o registro foi criado.

Então a afirmação correta é modesta: um id aleatório torna a enumeração inviável e esconde o seu tamanho. A correção do bug de fundo continua sendo uma verificação de permissão em toda requisição.

O que ele não protege?

Um link não listado é uma boa escolha quando "qualquer pessoa com o link" é justamente a intenção, como num documento compartilhado. É a escolha errada para dados privados, em que a página deveria verificar uma sessão independentemente de como a URL seja.

Quanto custa?

Se mesmo assim você ficar com UUIDs, o gerador de UUID pode tirar os hifens para uma forma de 32 caracteres. É mais curta de copiar, mas continua não sendo algo que uma pessoa consiga ditar, e a forma em minúsculas com hifens continua sendo a que convém guardar.

Quando um id sequencial é a melhor resposta?

Quando o registro é público de qualquer maneira. Números de artigo, números de ticket que os usuários citam de volta para você e números de nota fiscal não ganham nada por ficarem escondidos, e ganham muito por serem legíveis. Além disso, muitos regimes tributários esperam que os números de nota sigam uma sequência sem buracos, então confira o seu antes de trocá-los por sequências aleatórias.

Também funciona quando o acesso é verificado direito no servidor, porque aí um vizinho adivinhado devolve uma recusa e não um registro. O vazamento que sobra é a quantidade, que só importa se o seu volume é algo que você prefere manter privado.

Quais são as opções intermediárias?

Um atalho a evitar: bibliotecas que codificam um inteiro numa sequência de aparência aleatória. Elas são ofuscação reversível, não um segredo, então trate-as como algo cosmético.

Uma ferramenta consegue me dizer se minhas URLs são seguras?

Não, e vale ser claro sobre isso. O gerador de UUID cria identificadores v4 ou v7 no seu navegador e o inspetor dele lê a versão e, num v7, a hora de criação a partir dos bits. Ele não enxerga o seu servidor, então não consegue dizer se um endpoint verifica a propriedade do registro, se uma página de listagem vaza os ids ou se a sua fonte de aleatoriedade é sólida. Essa verificação é um teste que você faz contra a sua própria aplicação, logado como um usuário e pedindo o registro de outro.

Se você está pesando um id aleatório contra um contador, o gerador de UUID faz os dois tipos mil por vez para você ver o tamanho do resultado numa rota de verdade antes de decidir. Ele roda no seu navegador e nada do que você gerar é enviado a lugar nenhum.

E se o que você quer, no fundo, é um link que só uma pessoa deveria abrir, como enviar uma senha a alguém com segurança explica a diferença entre um link impossível de adivinhar e um segredo entregue do jeito certo.

Perguntas frequentes

É seguro colocar um UUID numa URL?

É seguro contra tentativas de adivinhar: um UUID v4 tem 122 bits aleatórios, então ninguém consegue percorrer os seus registros trocando o id. Não é seguro como substituto de um login, porque qualquer um que tenha a URL pode abri-la, e URLs vazam por logs, histórico e cabeçalhos Referer. Verifique as permissões no servidor independentemente de como o id seja.

Devo usar ids sequenciais ou UUIDs nas URLs?

Use ids sequenciais quando o registro é público ou as pessoas precisam citá-lo, e o acesso é verificado no servidor de qualquer forma. Use ids aleatórios quando a quantidade de registros é algo que você quer manter privado, ou quando uma permissão esquecida exporia os registros vizinhos. Muitos sistemas mantêm os dois: um inteiro dentro do banco de dados e um id público aleatório na URL.

Um UUID evita bugs de referência direta insegura a objetos?

Não. Ele os torna muito mais difíceis de explorar, porque um atacante não consegue adivinhar o id de outro registro, mas o bug é uma verificação de permissão ausente e continua lá. Se um UUID vaza por uma página de listagem, um e-mail ou um print compartilhado, o registro fica aberto para quem o encontrar.

Por que UUIDs são ruins para URLs legíveis?

Um UUID são 36 caracteres de hexadecimal e hifens que ninguém consegue ler em voz alta, memorizar ou comparar de relance. Um cliente que o cite por telefone vai errar. Se as pessoas precisam se referir ao registro, dê a ele um número curto pensado para humanos ou um slug legível ao lado do UUID.

Qual o tamanho necessário de um id aleatório numa URL?

O suficiente para que adivinhar às cegas seja inútil, dada a quantidade de tentativas que você permite. Dez caracteres de um alfabeto de 32 símbolos são 50 bits, cerca de um acerto a cada bilhão de tentativas contra um milhão de registros. Isso só vale se você limitar a frequência das requisições, e não diz nada sobre quem pode ver a página.

Última atualização 28 de setembro de 2026