Español

Herramientas de desarrollo · Codificador y decodificador de URL

Punycode vs codificación porcentual: cómo se manejan los dominios y rutas que no son ASCII

· Antecedentes

internacionalización código puny codificación de URL

Los nombres de dominio se convierten a punycode mientras que las rutas permanecen codificadas en porcentaje
Ilustración de vector original de ToolAcre

Una URL con un nombre de host que no sea ASCII y una ruta que no sea ASCII utiliza dos codificaciones completamente diferentes. Esta publicación explica IDNA y punycode para el host, codificación porcentual para todo lo demás y por qué existe la división.

La dirección que muestra 'münchen.example' en un navegador y 'xn--mnchen-3ya.example' en otro: un host, dos grafías

La ciudad München aparece en un nombre de dominio alemán. En la barra de direcciones de su navegador, es posible que vea münchen.example mostrado normalmente. Copie la dirección de una aplicación diferente y aparecerá como xn--mnchen-3ya.example, una cadena solo ASCII que no se parece en nada al texto alemán. Una URL, dos grafías, ambas absolutamente válidas. Ninguno de los dos está mal; representan el mismo dominio utilizando conjuntos de caracteres completamente diferentes. La diferencia refleja una limitación fundamental sobre cómo funciona el DNS y cómo la infraestructura de Internet espera que se transmitan los nombres de host.

Los segmentos de ruta como /café/ necesitan codificación pero usan un sistema diferente. é no ASCII se convierte en %C3%A9 en las rutas. ¿Por qué la diferencia? Las restricciones de DNS requieren punycode para los nombres de host.

Por qué los nombres de host no pueden usar codificación porcentual: etiquetas DNS, caracteres permitidos y límites de longitud

Las etiquetas DNS, los segmentos individuales de un nombre de host separados por puntos, tienen reglas muy estrictas. Sólo pueden contener letras ASCII, dígitos, guiones y guiones bajos. Tienen límites de longitud: cada etiqueta puede tener como máximo 63 octetos y el nombre de host completo no puede exceder los 255 octetos. Estas son restricciones estrictas del propio protocolo DNS, definido hace décadas antes de que los nombres de dominio internacionales fueran siquiera un concepto. La codificación porcentual no puede funcionar para nombres de host porque la cadena resultante probablemente excedería los límites de la etiqueta en palabras más largas.

Más importante aún, DNS es un sistema global operado por enrutadores y servidores en todo el mundo. No todos entienden UTF-8 o Unicode. Un carácter codificado por porcentaje como %C3%A9 sigue teniendo tres caracteres ASCII, por lo que se ajusta a las restricciones de DNS. Pero ese enfoque significa que cada búsqueda tiene que codificar porcentualmente al entrar y decodificar al salir, lo que agrega complejidad a la capa de protocolo en sí. Se necesitaba una mejor solución específicamente para los nombres de host.

IDNA y punycode en resumen: el prefijo xn-- y el algoritmo de cadena de arranque, descritos cualitativamente

IDNA, la especificación de nombres de dominio internacionalizados en aplicaciones, resuelve el problema de los nombres de host codificando nombres de dominio que no son ASCII en ASCII que DNS puede manejar. La codificación utilizada se llama punycode, un algoritmo de compresión que convierte el texto Unicode en ASCII usando el prefijo xn-- seguido de una representación codificada con cadena de arranque. El algoritmo es determinista: münchen siempre se convierte en xn--mnchen-3ya cada vez. Cualquier nombre de host que no sea ASCII debe convertirse de esta manera antes de que se pueda realizar la resolución DNS.

El prefijo xn-- indica al DNS y al software compatible con IDNA que los siguientes caracteres son punycode, no letras ASCII literales. Un dominio como ejemplo.xn--mnchen-3ya.com se entiende como ejemplo.münchen.com mediante software compatible con IDNA. Punycode utiliza sólo letras, dígitos y guiones ASCII, por lo que encaja perfectamente en las etiquetas DNS sin problemas. El algoritmo comprime la información que no es ASCII en esta representación ASCII.

Las rutas, consultas y fragmentos permanecen codificados en porcentaje: UTF-8 bytes a %XX, como en otros lugares

Todo lo demás en una URL (la ruta, la cadena de consulta, el fragmento) utiliza codificación porcentual. Un carácter que no es ASCII primero se convierte en UTF-8 bytes y luego cada byte se escribe como %HH, donde HH es hexadecimal. La ruta /café/ se convierte en /caf%C3%A9/.. La cadena de consulta ?name=josé se convierte en ?name=jos%C3%A9. La codificación porcentual es estándar en todas partes de la web: en las URL de solicitud HTTP, en los formularios HTML y en las API. No necesita manejo especial por parte de DNS o enrutadores.

La codificación porcentual también permite representar de forma segura otros caracteres especiales. Un espacio se convierte en %20, una barra diagonal (si debe aparecer dentro de un valor) se convierte en %2F, y así sucesivamente. El esquema es consistente y universal. No se utiliza para nombres de host porque DNS no comprende las URL ni la codificación porcentual; sólo entiende etiquetas ASCII.

Ejemplo resuelto: una URL con ambas: el host convertido a punycode, la ruta codificada en porcentaje, una al lado de la otra

Tome la URL "https://münchen.example/café?city=münchen". El nombre de host münchen debe convertirse a punycode antes de la búsqueda de DNS: https://xn--mnchen-3ya.example/café?city=münchen. Pero espere, la ruta y la consulta tampoco son ASCII. Conviértalos también: https://xn--mnchen-3ya.example/caf%C3%A9?city=m%C3%BCnchen. Ahora el nombre de host es punycode, la ruta y la consulta están codificadas en porcentaje. Un navegador muestra la versión Unicode original para facilitar la lectura; la solicitud HTTP lleva el versión codificada.

En la herramienta codificador y decodificador de URL, pegue una ruta que contenga texto que no sea ASCII y compare el modo de valor único (solo la ruta) con el modo de dirección completa (URL completa). La herramienta le muestra el resultado codificado en porcentaje para la ruta. El nombre de host, sin embargo, requiere una conversión de código punycode por separado; la mayoría de las herramientas de codificación no manejan eso en línea, así que léalo en la documentación de la herramienta.

Ataques homógrafos y por qué los navegadores a veces muestran punycode: el razonamiento de seguridad detrás de las reglas de visualización

Un actor malintencionado podría registrar un dominio utilizando letras cirílicas que parecen visualmente idénticas a las letras latinas, como "https://xn--80akhbyknj4f.example" (una versión cirílica de "example.example" en punycode). Si un navegador lo muestra decodificado como texto cirílico, es posible que los usuarios no noten la diferencia. Para evitar ataques homógrafos, los navegadores a veces muestran la versión punycode en lugar de decodificarla. Aparece una advertencia: este dominio no es total o mayoritariamente ASCII y es posible que no reconozca los caracteres.

El codificador y descodificador de URL es una herramienta para codificar y decodificar, no para evaluar la seguridad. Si está trabajando con nombres de dominio internacionales, tenga en cuenta que la representación punycode es lo que ve la red.

Lo que esto no cubre: ejecutar el algoritmo punycode manualmente o las diferencias de IDNA 2003 versus 2008

IDNA ha pasado por múltiples versiones a lo largo del tiempo: IDNA 2003 e IDNA 2008 manejan ciertos casos extremos de manera diferente, particularmente en torno a la normalización y qué caracteres Unicode están permitidos por especificación. Algunos sistemas más antiguos todavía usan IDNA 2003 mientras que otros han migrado a IDNA 2008 para un mejor cumplimiento. Las diferencias son muy importantes si está creando sistemas que deben ser compatibles en varias versiones. Siempre verifique cuidadosamente los requisitos de su sistema.

Punycode utiliza compresión de cadena de arranque. Existen implementaciones en lenguajes comunes, pero verifique la política de IDNA con su sistema de nombres de host. Pruebe la resolución y el comportamiento de visualización en lugar de suponer.

Conclusión: dos codificaciones para dos trabajos: cómo el codificador y descodificador de URL maneja las partes codificadas por porcentaje y por qué un codificador porcentual es la herramienta incorrecta para el nombre de host

Los nombres de host necesitan punycode porque DNS es un protocolo antiguo que solo entiende etiquetas ASCII y tiene restricciones estrictas de longitud y caracteres. Las rutas, consultas y fragmentos utilizan codificación porcentual porque es universal en la web y no tiene esas restricciones. Son dos soluciones separadas para dos problemas completamente diferentes. Cuando encuentra una URL que no es ASCII, el nombre de host obtiene primero la conversión de punycode y luego el resto usa codificación porcentual.

Para la mayoría del trabajo de desarrollo, su marco o biblioteca maneja esta conversión automáticamente en segundo plano. Pero comprender por qué existen dos codificaciones diferentes evita la confusión al depurar URL internacionales o implementar con éxito su propio código de manejo de URL.