Caractères autorisés dans les cookies

celui-ci est un quickie:

Quels sont les caractères autorisés dans le nom et la valeur du cookie? Sont-ils identiques à l’URL ou à un sous-ensemble commun?

La raison pour laquelle je pose la question est que j’ai récemment rencontré un comportement étrange avec des cookies qui - en leur nom et je me demande si c’est quelque chose de spécifique au navigateur ou si mon code est défectueux.

celui-ci est un quickie:

Vous pourriez penser que ça devrait être le cas, mais vraiment pas du tout!

Quels sont les caractères autorisés dans le nom et la valeur du cookie?

Selon l’ancienne Netscape cookie_spec, la chaîne NAME=VALUE entière est:

une séquence de caractères à l’exclusion des points-virgules, des virgules et des espaces blancs.

Donc - ça devrait marcher, et ça semble bien aller dans les navigateurs que j’ai ici; Où avez-vous des problèmes avec ça?

Par implication de ce qui précède:

  • = est légal à inclure, mais potentiellement ambigu. Les navigateurs divisent toujours le nom et la valeur sur le premier symbole de la chaîne. En pratique, vous pouvez mettre un symbole = dans la valeur mais pas le nom.

Ce qui n’est pas mentionné, parce que Netscape était terrible à écrire des spécifications, mais semble être supporté de manière cohérente par les navigateurs:

  • soit le NOM ou la VALEUR peuvent être des chaînes vides

  • s’il n’y a pas de symbole dans la chaîne, les navigateurs le traitent comme le cookie avec le nom de chaîne vide, par exemple Set-Cookie: foo est identique à Set-Cookie: =foo .

  • Lorsque les navigateurs génèrent un cookie avec un nom vide, ils omettent le signe égal. Donc Set-Cookie: =bar engendre Cookie: bar .

  • les virgules et les espaces dans les noms et les valeurs semblent réellement fonctionner, bien que les espaces autour du signe égal soient coupés

  • les caractères de contrôle ( \x00 à \x1F plus \x7F ) ne sont pas autorisés

Ce qui n’est pas mentionné et les navigateurs sont totalement incohérents à propos des caractères non-ASCII (Unicode):

  • dans Opera et Google Chrome, ils sont encodés dans les en-têtes de cookies avec UTF-8;
  • dans IE, la page de code par défaut de la machine est utilisée (spécifique à l’environnement local et jamais UTF-8);
  • Firefox (et les autres navigateurs basés sur Mozilla) utilisent l’octet bas de chaque sharepoint code UTF-16 (la norme ISO-8859-1 est correcte, mais tout le rest est altéré);
  • Safari refuse simplement d’envoyer un cookie contenant des caractères non-ASCII.

en pratique, vous ne pouvez donc pas utiliser de caractères non-ASCII dans les cookies. Si vous voulez utiliser Unicode, des codes de contrôle ou d’autres séquences d’octets arbitraires, cookie_spec vous demande d’utiliser un schéma de codage ad hoc de votre choix et de suggérer un codage URL (produit par l’ encodeURIComponent de JavaScript) comme un choix raisonnable.

En ce qui concerne les normes actuelles , il y a eu quelques tentatives de codification du comportement des cookies, mais jusqu’à présent, aucune ne reflète réellement le monde réel.

  • RFC 2109 était une tentative de codifier et de réparer le cookie_spec Netscape d’origine. Dans cette norme, beaucoup plus de caractères spéciaux sont interdits, car ils utilisent des jetons RFC 2616 (un - est toujours autorisé), et seule la valeur peut être spécifiée dans une chaîne entre guillemets avec d’autres caractères. Aucun navigateur n’a jamais implémenté les limitations, le traitement spécial des chaînes et des échappements cités, ni les nouvelles fonctionnalités de cette spécification.

  • La RFC 2965 en était une autre, rangeant 2109 et ajoutant plus de fonctionnalités sous un schéma de ‘version 2 cookies’. Personne n’a jamais rien mis en œuvre non plus. Cette spécification a les mêmes limitations de chaîne de caractères et de guillemets que la version précédente et est tout autant une charge de non-sens.

  • La RFC 6265 est une tentative du HTML5 pour effacer le désordre historique. Cela ne correspond toujours pas exactement à la réalité mais c’est bien mieux que les tentatives précédentes – il s’agit au moins d’un sous-ensemble de ce que les navigateurs supportent, n’introduisant aucune syntaxe censée fonctionner mais pas (comme la précédente chaîne) .

En 6265, le nom du cookie est toujours spécifié comme token RFC 2616, ce qui signifie que vous pouvez choisir parmi les alphanums, plus:

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

Dans la valeur de cookie, il interdit formellement les caractères de contrôle (filtrés par les navigateurs) et les caractères non-ASCII (implémentés de manière non cohérente). Il conserve l’interdiction de cookie_spec sur l’espace, les virgules et les points-virgules, ainsi que la compatibilité avec les mauvais idiots qui ont implémenté les anciennes RFC, ainsi que les guillemets, mais les guillemets sont toujours considérés comme faisant partie de la valeur, pas un schéma de codage). Alors ça vous laisse avec les alphanums plus:

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

Dans le monde réel, nous utilisons toujours le Netscape cookie_spec original, et le code qui consum des cookies devrait être prêt à faire face à presque tout, mais pour le code qui produit des cookies, il est conseillé de respecter le sous-ensemble de la RFC 6265.

Dans ASP.Net, vous pouvez utiliser System.Web.HttpUtility pour encoder en toute sécurité la valeur du cookie avant d’écrire sur le cookie et la reconvertir dans sa forme originale en la lisant.

 // Encode HttpUtility.UrlEncode(cookieData); // Decode HttpUtility.UrlDecode(encodedCookieData); 

Cela arrêtera les esperluettes et les signes égaux divisant une valeur en un groupe de paires nom / valeur, car il est écrit dans un cookie.

Je pense que c’est généralement spécifique au navigateur. Pour être du bon côté, base64 code un object JSON et stocke tout cela. De cette façon, il vous suffit de le décoder et d’parsingr le JSON. Tous les caractères utilisés dans base64 doivent être compatibles avec la plupart, voire tous les navigateurs.

Rfc6265 plus récent publié en avril 2011:

 cookie-header = "Cookie:" OWS cookie-ssortingng OWS cookie-ssortingng = cookie-pair *( ";" SP cookie-pair ) cookie-pair = cookie-name "=" cookie-value cookie-value = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE ) cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E ; US-ASCII characters excluding CTLs, ; whitespace DQUOTE, comma, semicolon, ; and backslash 

Si vous cherchez à @bobince, répondez que la nouvelle ressortingction est plus ssortingcte.

vous ne pouvez pas mettre “;” dans le champ de valeur d’un cookie, le nom qui sera défini est la chaîne jusqu’à la “;” dans la plupart des navigateurs …

La voici en peu de mots . Concentrez-vous sur les personnages qui ne nécessitent aucune fuite:

Pour les cookies:

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

Pour les URL

 abdefghijklmnqrstuvxyzABDEFGHIJKLMNQRSTUVXYZ0123456789.-_~!$&'()*+,;=:@ 

Pour les cookies et les URL (intersection)

 abdefghijklmnqrstuvxyzABDEFGHIJKLMNQRSTUVXYZ0123456789!$&'()*+-.:@_~ 

C’est comme ça que tu réponds.

Notez que pour les cookies, le = a été supprimé car il est généralement utilisé pour définir la valeur du cookie.

Pour les URL, le = a été conservé. L’intersection est évidemment sans.

 var chars = "abdefghijklmnqrstuvxyz"; chars += chars.toUpperCase() + "0123456789" + "!$&'()*+-.:@_~"; 

Il s’avère qu’il est toujours possible d’échapper à des événements inattendus, en particulier dans un environnement de cookie Java où le cookie est entouré de guillemets s’il rencontre les derniers caractères.

Donc, pour être sûr, utilisez simplement A-Za-z1-9. C’est ce que je vais faire.

Il existe 2 versions de spécifications de cookies
1. les cookies de la version 0, alias cookies de Netscape,
2. Version 1 aka RFC 2965 cookies
Dans la version 0 Le nom et la partie valeur des cookies sont des séquences de caractères, à l’exclusion du point-virgule, de la virgule, du signe égal et de l’espace, s’ils ne sont pas utilisés avec des guillemets
la version 1 est beaucoup plus compliquée, vous pouvez la vérifier ici
Dans cette version, les spécifications pour la partie valeur de nom sont presque identiques, sauf que nom ne peut pas commencer par $

Désolé, je ne pouvais pas append à la réponse acceptée, mais je me suis heurté à un autre problème intéressant avec IE et Edge.

Les cookies dont les noms comportent plus d’une période semblent être supprimés en silence. Donc cela fonctionne:

cookie_name_a = valeur

alors que cela va tomber

cookie.name.a = valeur

Il y a des années, MSIE 5 ou 5.5 (et probablement les deux) avaient un sérieux problème avec un “-” dans le bloc HTML si vous pouvez le croire. Bien que cela ne soit pas directement lié, depuis que nous avons stocké un hachage MD5 (contenant uniquement des lettres et des chiffres) dans le cookie pour rechercher tout le rest dans la firebase database côté serveur.