Ferramentas de desenvolvedor · Codificador e decodificador URL
Punycode vs codificação percentual: como domínios e caminhos não ASCII são tratados
· Fundo
internacionalização código puny codificação de URL
Um URL com um nome de host não ASCII e um caminho não ASCII usa duas codificações completamente diferentes. Esta postagem explica IDNA e punycode para o host, codificação percentual para todo o resto e por que existe a divisão.
O endereço que mostra 'münchen.example' em um navegador e 'xn--mnchen-3ya.example' em outro — um host, duas grafias
A cidade München aparece num nome de domínio alemão. Na barra de endereço do seu navegador, você poderá ver münchen.example exibido normalmente. Copie o endereço de um aplicativo diferente e ele aparecerá como xn--mnchen-3ya.example, uma string somente ASCII que não se parece em nada com texto em alemão. Um URL, duas grafias, ambas absolutamente válidas. Nenhum dos dois está errado; eles representam o mesmo domínio usando conjuntos de caracteres completamente diferentes. A diferença reflete uma restrição fundamental sobre como DNS funciona e como a infraestrutura da Internet espera que os nomes de host sejam transmitidos.
Segmentos de caminho como /café/ precisam de codificação, mas usam um sistema diferente. Não-ASCII é se torna %C3%A9 em caminhos. Por que a diferença? As restrições DNS requerem punycode para nomes de host.
Por que os nomes de host não podem usar codificação percentual — rótulos DNS, caracteres permitidos e limites de comprimento
Os rótulos DNS, os segmentos individuais de um nome de host separados por pontos, têm regras muito rígidas. Eles só podem conter ASCII letras, dígitos, hifens e sublinhados. Eles têm limites de comprimento: cada rótulo pode ter no máximo 63 octetos e o nome do host completo não pode exceder 255 octetos. Estas são restrições rígidas do próprio protocolo DNS, definido décadas atrás, antes mesmo de nomes de domínio internacionais serem um conceito. A codificação percentual não funciona para nomes de host porque a sequência resultante provavelmente excederia os limites de rótulo em palavras mais longas.
Mais importante ainda, DNS é um sistema global operado por roteadores e servidores em todo o mundo. Nem todos entendem UTF-8 ou Unicode. Um caractere codificado por porcentagem como %C3%A9 ainda tem três caracteres ASCII, portanto, ele se ajusta às restrições DNS. Mas essa abordagem significa que cada pesquisa precisa codificar por cento na entrada e decodificar na saída, adicionando complexidade à própria camada de protocolo. Uma solução melhor era necessária especificamente para nomes de host.
IDNA e punycode em destaque — o prefixo xn-- e o algoritmo de bootstring, descritos qualitativamente
IDNA, a especificação de nomes de domínio internacionalizados em aplicativos, resolve o problema do nome do host codificando nomes de domínio não ASCII em ASCII que DNS pode manipular. A codificação usada é chamada punycode, um algoritmo de compactação que transforma texto Unicode em ASCII usando o prefixo xn-- seguido por uma representação codificada por bootstring. O algoritmo é determinístico: münchen sempre se torna xn--mnchen-3ya todas as vezes. Qualquer nome de host não ASCII deve ser convertido desta forma antes que a resolução DNS possa acontecer.
O prefixo xn-- sinaliza para DNS e para software compatível com IDNA que os caracteres a seguir são punycode, e não letras ASCII literais. Um domínio como example.xn--mnchen-3ya.com significa example.münchen.com por software compatível com IDNA. O Punycode usa apenas ASCII letras, dígitos e hifens, portanto, cabe perfeitamente nos rótulos DNS sem problemas. O algoritmo compacta as informações não ASCII nesta representação ASCII.
Caminhos, consultas e fragmentos permanecem codificados por porcentagem — UTF-8 bytes para %XX, como em outros lugares
Todo o resto em um URL — o caminho, a string de consulta, o fragmento — usa codificação percentual. Um caractere não ASCII é primeiro convertido em UTF-8 bytes e, em seguida, cada byte é escrito como%HH, onde HH é hexadecimal. O caminho /café/ torna-se /caf%C3%A9/. A string de consulta ?name=josé torna-se ?name=jos%C3%A9. A codificação percentual é padrão em todos os lugares da web: em URLs de solicitação HTTP, em formulários HTML, em APIs. Não precisa de tratamento especial por DNS ou roteadores.
A codificação percentual também permite que outros caracteres especiais sejam representados com segurança. Um espaço se torna %20, uma barra (se deve aparecer dentro de um valor) se torna %2F e assim por diante. O esquema é consistente e universal. Não é usado para nomes de host porque DNS não entende URLs ou codificação percentual; ele entende apenas rótulos ASCII.
Exemplo resolvido: um URL com ambos - o host convertido em punycode, o caminho codificado por porcentagem, lado a lado
Pegue o URL "https://münchen.example/café?city=münchen". O nome do host münchen deve ser convertido para punycode antes da pesquisa de DNS: https://xn--mnchen-3ya.example/café?city=münchen. Mas espere - o caminho e a consulta também não têm ASCII. Converta-os também: https://xn--mnchen-3ya.example/caf%C3%A9?city=m%C3%BCnchen. Agora o nome do host é punycode, o caminho e a consulta são codificados por porcentagem. A o navegador exibe a versão Unicode original para facilitar a leitura; a solicitação HTTP carrega a versão codificada.
Na ferramenta de codificador e decodificador URL, cole um caminho contendo texto não ASCII e compare o modo de valor único (apenas o caminho) com o modo de endereço completo (URL completo). A ferramenta mostra o resultado codificado em porcentagem para o caminho. O nome do host, entretanto, requer conversão separada de punycode; a maioria das ferramentas de codificação não lida com isso inline, então leia na documentação da ferramenta.
Ataques homógrafos e por que os navegadores às vezes mostram punycode — o raciocínio de segurança por trás das regras de exibição
Um ator mal-intencionado pode registrar um domínio usando letras cirílicas que parecem visualmente idênticas às letras latinas, como "https://xn--80akhbyknj4f.example" (uma versão cirílica de "example.example" em punycode). Se um navegador o exibir decodificado como texto cirílico, os usuários podem não notar a diferença. Para evitar ataques homógrafos, os navegadores às vezes mostram a versão punycode em vez de decodificá-la. Um aviso aparece: este domínio é todo ou quase todo não-ASCII e você pode não reconhecer os personagens.
O codificador e decodificador URL é uma ferramenta para codificação e decodificação, não para avaliação de segurança. Se você estiver trabalhando com nomes de domínio internacionais, esteja ciente de que a representação punycode é o que a rede vê.
O que isso não cobre - executar o algoritmo punycode manualmente ou as diferenças IDNA 2003 versus 2008
IDNA passou por várias versões ao longo do tempo: IDNA 2003 e IDNA 2008 lidam com certos casos extremos de maneira diferente, especialmente em torno da normalização e quais caracteres Unicode são permitidos pela especificação. Alguns sistemas mais antigos ainda usam IDNA 2003 enquanto outros migraram para IDNA 2008 para melhor conformidade. As diferenças são significativamente importantes se você estiver construindo sistemas que devem ser compatíveis entre diversas versões. Verifique sempre os requisitos do sistema com cuidado.
Punycode usa compactação de bootstring. Existem implementações em linguagens comuns, mas verifique a política IDNA com seu sistema de nome de host. Teste a resolução e o comportamento de exibição em vez de presumir.
Conclusão: duas codificações para dois trabalhos - como o codificador e decodificador URL lida com as partes codificadas por porcentagem e por que um codificador por porcentagem é a ferramenta errada para o nome do host
Os nomes de host precisam de punycode porque DNS é um protocolo antigo que entende apenas rótulos ASCII e tem restrições estritas de comprimento e caracteres. Caminhos, consultas e fragmentos usam codificação percentual porque é universal na web e não possui essas restrições. São duas soluções distintas para dois problemas completamente diferentes. Quando você encontra um não-ASCII URL, o nome do host obtém a conversão punycode primeiro, depois o restante usa a codificação percentual.
Para a maior parte do trabalho de desenvolvimento, sua estrutura ou biblioteca lida com essa conversão nos bastidores automaticamente. Mas entender por que existem duas codificações diferentes evita confusão ao depurar URLs internacionais ou implementar seu próprio código de manipulação URL com êxito.