Português (Brasil)

Ferramentas para desenvolvedores · Gerador UUID

Por que crypto.randomUUID() falha nas páginas HTTP: contextos seguros explicados

· Como funciona

uuid criptografia APIs do navegador

Três origens mostradas: HTTPS com crypto.randomUUID disponível, localhost com crypto.randomUUID disponível, servidor de teste HTTP com randomUUID bloqueado
Ilustração vetorial original ToolAcre

crypto.randomUUID funciona em localhost e em HTTPS e depois desaparece em um host de teste simples-HTTP. Esta postagem explica a regra de contexto seguro por trás desse comportamento e como gerar um UUID com segurança onde ele se aplica.

TypeError no teste, bom em qualquer outro lugar - o sintoma e a diferença de ambiente que o causa

Um desenvolvedor verifica seu trabalho em localhost:3000 e o gerador UUID funciona perfeitamente. Eles são implantados para teste em http://staging. interno. exemplo. com (simples HTTP na empresa LAN) e o código lança TypeError: crypto.randomUUID não é uma função. O mesmo código em produção em https://example. com funciona bem. A inconsistência é desconcertante até que eles leiam os documentos MDN: crypto.randomUUID está restrito a contextos seguros. Um contexto seguro é HTTPS ou localhost; uma origem plain-HTTP em um LAN não é segura pela regra do navegador, mesmo que a rede seja privada. A correção é usar crypto.getRandomValues com operações manuais de bits ou atualizar o servidor temporário para HTTPS. A regra de contexto seguro foi introduzida para evitar que APIs confidenciais vazem para conexões não criptografadas.

O que é um contexto seguro — a regra do navegador que reserva certas APIs para origens HTTPS e para localhost

Uma página HTTP simples pode ser interceptada por um invasor de rede; expor APIs criptográficas a tal página tornaria possível para um invasor gerar identificadores usando um API comprometido. HTTPS criptografa a página e todas as comunicações API para que um invasor na rede não possa interceptar ou modificar o código. Localhost é tratado como inerentemente seguro porque existe apenas na máquina local e não pode ser interceptado pela rede. Qualquer outra origem HTTP (um endereço LAN, um domínio público sem HTTPS, um proxy reverso que encaminha para HTTP) não é segura por definição. O Web Crypto API é dividido em duas funções: crypto.randomUUID, restrita a contextos seguros, e crypto.getRandomValues, disponível em contextos seguros e não seguros. Ambos usam o mesmo sistema operacional CSPRNG.

Quais partes do Web Crypto são bloqueadas - crypto.randomUUID e crypto.subtle requerem um contexto seguro, enquanto crypto.getRandomValues não

A diferença é que getRandomValues ​​não esconde o fato de que você está usando criptografia; uma página que o utiliza deve solicitar explicitamente bytes aleatórios. A função randomUUID é uma conveniência que também impõe contexto seguro. Se seu aplicativo precisar gerar UUIDs em uma página não segura, você deverá usar getRandomValues ​​e definir manualmente a versão e os bits de variante. RFC 9562 especifica as operações de bits: defina o byte 6 para (byte6 e 0x0f) | 0x40 para versão 4 e byte 8 para (byte8 e 0x3f) | 0x80 para variante RFC. A biblioteca ToolAcre faz exatamente isso como alternativa quando randomUUID não está disponível. Reproduzindo a falha: forneça uma página simples de uma origem HTTP simples que não seja tratada como potencialmente confiável. Verifique se randomUUID está exposto e compare getRandomValues, que a referência Web Crypto permite em contextos inseguros.

Construindo um UUID v4 a partir de getRandomValues ​​- o substituto de mascaramento e formatação que mantém você no CSPRNG quando randomUUID está faltando

O mesmo código em um arquivo veiculado em HTTPS pode expor randomUUID. Se a produção relatar que "randomUUID não é uma função", primeiro inspecione se a origem é um contexto seguro e, em seguida, verifique o suporte do navegador e se outro script substituiu o objeto criptográfico. A solução pode ser HTTPS ou uma implementação getRandomValues ​​que defina os bits UUID explicitamente. Um polyfill Math.random não é um substituto equivalente: ele reproduz a forma enquanto descarta o contrato de origem criptográfica. Os testes que afirmam apenas travessões e dígitos de versão perderão essa substituição, portanto, revise o caminho de origem, bem como a string resultante.

Exemplo resolvido — reproduzindo a falha em uma origem http:// e confirmando a correção

Mas o identificador agora é previsível. Um invasor que captura alguns UUIDs do seu sistema pode prever o próximo. Se um aplicativo tratar erroneamente tal identificador como uma credencial de portador, a previsibilidade se tornará uma falha de autorização e não um defeito cosmético. A estratégia correta é atualizar o servidor para HTTPS (sempre a medida certa para qualquer página com autenticação ou dados confidenciais) ou usar getRandomValues ​​com operações de bits explícitas (que exigem mais código, mas são criptograficamente corretas). O contexto seguro é imposto pelo navegador; você não pode contornar isso com variáveis ​​de configuração ou de ambiente. O gerador ToolAcre é implantado em HTTPS, portanto, crypto.randomUUID está disponível. Quando você gera um UUID na ferramenta, ele usa randomUUID (se a verificação de contexto seguro for aprovada) ou getRandomValues ​​com operações de bit (se você estiver em HTTP simples, embora isso seja raro).

Por que você não deve usar polyfill com Math.random — o atalho tentador e o custo de segurança que ele acarreta

Nenhum dos caminhos retorna para Math.random. Se você estiver construindo seu próprio gerador UUID e visando origens não seguras, use getRandomValues ​​e faça você mesmo as operações de bits. Teste em HTTPS e localhost para confirmar que randomUUID funciona e, em seguida, teste em uma origem http:// para confirmar se seu substituto getRandomValues ​​está correto. Compreender a restrição do contexto seguro ajuda a projetar estratégias de implantação. Se seu aplicativo precisar ser executado em um LAN privado sem HTTPS (infraestrutura legada, sistemas incorporados), o substituto getRandomValues ​​é o seu caminho a seguir. Se você tiver escolha, atualize para HTTPS em qualquer lugar; é gratuito com o Let's Encrypt e o investimento é recompensado em segurança em todo o aplicativo. O desenvolvimento no localhost não tem restrições, então teste seu gerador UUID no localhost e na preparação HTTPS antes de implantar na produção. A produção deve sempre ser HTTPS.

O que isso não cobre: ​​tempos de execução de servidores como Node.js e Deno, que expõem API sem uma regra de contexto seguro

A restrição não é um bug ou um incômodo; é um recurso de segurança que evita acidentes e obriga você a pensar em criptografia. O padrão mais amplo é que as APIs de criptografia da web são controladas por contexto seguro. crypto.getRandomValues, criptografia. sutil. criptografar, criptografar. sutil. generateKey e todas as outras operações confidenciais requerem HTTPS ou localhost. Não há exceção, nenhuma substituição, nenhuma maneira de desabilitar a verificação. Uma única página insegura quebra as garantias de segurança de seus usuários. Mesmo se você tiver o cuidado de usar APIs de criptografia apenas em determinadas páginas, um erro (ou uma dependência que inclua um gerador UUID) pode vazar a geração de aleatoriedade para uma página não criptografada. O gerador ToolAcre impõe isso no nível do código: se randomUUID não estiver disponível (contexto não seguro), ele usa getRandomValues, que está disponível, mas alerta qualquer revisor de código que algo incomum está acontecendo.

Conclusão: corrija a origem, não o gerador — ToolAcre é veiculado em HTTPS, portanto, seu gerador é executado em um contexto seguro por design

Melhor ainda, ele se recusa a gerar um identificador se o contexto seguro estiver realmente indisponível (em ambientes onde getRandomValues ​​também não está disponível, o que é raro, mas possível em sistemas mais antigos ou embarcados). Migrar um sistema existente para HTTPS para oferecer suporte a APIs de criptografia segura é um projeto comum. Comece com a origem onde os UUIDs são gerados (seu servidor de autenticação, back-end API ou serviço de aplicativo principal). Adquira um certificado TLS (Let's Encrypt os fornece gratuitamente). Configure seu servidor web para atender HTTPS por padrão e redirecione solicitações HTTP para HTTPS. Teste com vários navegadores e clientes API para garantir que tudo funcione. Em seguida, audite seu código para detectar quaisquer APIs criptográficas restantes que possam ser chamadas em páginas não criptografadas e corrija-as. O gerador ToolAcre assume HTTPS; se você estiver usando, você já fez parte do caminho.