¿Cuáles son los caracteres permitidos en las cookies?

Resuelto Esko asked hace 14 años • 13 respuestas

¿Cuáles son los caracteres permitidos tanto en el nombre como en el valor de la cookie? ¿Son iguales que la URL o algún subconjunto común?

La razón por la que pregunto es que recientemente encontré un comportamiento extraño con las cookies que tienen -su nombre y me pregunto si es algo específico del navegador o si mi código es defectuoso.

Esko avatar Dec 28 '09 19:12 Esko
Aceptado

Según la antigua cookie_spec de Netscape, la cadena completa NAME=VALUEes:

una secuencia de caracteres excluyendo punto y coma, coma y espacios en blanco.

Debería -funcionar, y parece estar bien en los navegadores que tengo aquí; ¿Dónde tienes problemas con eso?

Por implicación de lo anterior:

  • =Es legal incluirlo, pero potencialmente ambiguo. Los navegadores siempre dividen el nombre y el valor en el primer =símbolo de la cadena, por lo que en la práctica puedes poner un =símbolo en el VALOR pero no en el NOMBRE.

Lo que no se menciona, porque Netscape fue terrible escribiendo especificaciones, pero parece ser compatible constantemente con los navegadores:

  • ya sea el NOMBRE o el VALOR pueden ser cadenas vacías

  • Si no hay ningún =símbolo en la cadena, los navegadores la tratan como la cookie con el nombre de cadena vacía, es decir, Set-Cookie: fooes lo mismo que Set-Cookie: =foo.

  • cuando los navegadores generan una cookie con un nombre vacío, omiten el signo igual. Así Set-Cookie: =barengendra Cookie: bar.

  • las comas y los espacios en nombres y valores realmente parecen funcionar, aunque los espacios alrededor del signo igual están recortados

  • Los caracteres de control ( \x00a \x1Fmás \x7F) no están permitidos.

Lo que no se menciona y los navegadores son totalmente inconsistentes son los caracteres que no son ASCII (Unicode):

  • en Opera y Google Chrome, están codificados en encabezados de cookies con UTF-8;
  • en IE, se utiliza la página de códigos predeterminada de la máquina (específica de la configuración regional y nunca UTF-8);
  • Firefox (y otros navegadores basados ​​en Mozilla) utilizan el byte bajo de cada punto de código UTF-16 por sí solo (por lo que ISO-8859-1 está bien, pero todo lo demás está alterado);
  • Safari simplemente se niega a enviar cookies que contengan caracteres que no sean ASCII.

por lo que, en la práctica, no se pueden utilizar caracteres que no sean ASCII en las cookies. Si desea utilizar Unicode, códigos de control u otras secuencias de bytes arbitrarias, cookie_spec exige que utilice un esquema de codificación ad-hoc de su propia elección y sugiere la codificación de URL (producida por JavaScript encodeURIComponent) como una opción razonable.

En términos de estándares reales , ha habido algunos intentos de codificar el comportamiento de las cookies, pero hasta ahora ninguno refleja el mundo real.

  • RFC 2109 fue un intento de codificar y corregir la cookie_spec original de Netscape. En este estándar, muchos más caracteres especiales no están permitidos, ya que utiliza tokens RFC 2616 (a todavía- está permitido allí), y solo se puede especificar el valor en una cadena entrecomillada con otros caracteres. Ningún navegador implementó nunca las limitaciones, el manejo especial de cadenas entre comillas y el escape, ni las nuevas funciones de esta especificación.

  • RFC 2965 fue otro intento, ordenando 2109 y agregando más funciones bajo un esquema de 'cookies de versión 2'. Nadie implementó nada de eso tampoco. Esta especificación tiene las mismas limitaciones de tokens y cadenas entre comillas que la versión anterior y es un montón de tonterías.

  • RFC 6265 es un intento de la era HTML5 de aclarar el desorden histórico. Todavía no coincide exactamente con la realidad, pero es mucho mejor que los intentos anteriores: es al menos un subconjunto adecuado de lo que admiten los navegadores, sin introducir ninguna sintaxis que se supone que funciona pero que no funciona (como la cadena entre comillas anterior). .

En 6265, el nombre de la cookie todavía se especifica como RFC 2616 token, lo que significa que puede elegir entre alphanums y:

!#$%&'*+-.^_`|~

En el valor de la cookie, prohíbe formalmente los caracteres de control (filtrados por los navegadores) y los caracteres no ASCII (implementados de manera inconsistente). Mantiene la prohibición de cookie_spec sobre espacios, comas y punto y coma, además, por compatibilidad con cualquier pobre idiota que haya implementado los RFC anteriores, también prohibió la barra invertida y las comillas, excepto las comillas que envuelven el valor completo (pero en ese caso las comillas aún se consideran parte de el valor, no un esquema de codificación). Eso te deja con los alphanums más:

!#$%&'()*+-./:<=>?@[]^_`{|}~

En el mundo real todavía utilizamos la cookie_spec original y peor de Netscape, por lo que el código que consume cookies debe estar preparado para encontrar prácticamente cualquier cosa, pero para el código que produce cookies es recomendable seguir con el subconjunto en RFC 6265.

bobince avatar Dec 28 '2009 12:12 bobince

En ASP.Net, puede utilizarlo System.Web.HttpUtilitypara codificar de forma segura el valor de la cookie antes de escribirla y convertirla nuevamente a su forma original al leerla.

// Encode
HttpUtility.UrlEncode(cookieData);

// Decode
HttpUtility.UrlDecode(encodedCookieData);

Esto evitará que los signos ampersand y igual dividan un valor en un grupo de pares de nombre/valor tal como se escribe en una cookie.

stephen avatar Feb 28 '2011 15:02 stephen

Creo que generalmente es específico del navegador. Para estar seguro, base64 codifica un objeto JSON y almacena todo en él. De esa forma sólo tendrás que decodificarlo y analizar el JSON. Todos los caracteres utilizados en base64 deberían funcionar bien con la mayoría, si no con todos, los navegadores.

Jamie Rumbelow avatar Dec 28 '2009 12:12 Jamie Rumbelow