celui-ci est un quickie:
Vous pourriez penser que cela devrait l'être, mais ce n'est vraiment pas du tout!
Quels sont les caractères autorisés dans le nom et la valeur du cookie?
Selon l'ancien cookie_spec de Netscape, la NAME=VALUE
chaîne entière est:
une séquence de caractères excluant les points-virgules, les virgules et les espaces blancs.
-
Cela devrait donc fonctionner, et cela semble être OK 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, donc en pratique vous pouvez mettre un =
symbole dans la VALEUR mais pas le NOM.
Ce qui n'est pas mentionné, car Netscape était horrible lors de l'écriture de spécifications, mais semble toujours pris en charge par les navigateurs:
le NOM ou la VALEUR peuvent être des chaînes vides
s'il n'y a aucun =
symbole dans la chaîne, les navigateurs le traitent comme le cookie avec le nom de chaîne vide, c'est Set-Cookie: foo
-à- dire le même que Set-Cookie: =foo
.
lorsque les navigateurs génèrent un cookie avec un nom vide, ils omettent le signe égal. Alors 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
en \x1F
plus \x7F
) ne sont pas autorisés
Ce qui n'est pas mentionné et les navigateurs sont totalement incohérents, ce sont les caractères non ASCII (Unicode):
- dans Opera et Google Chrome, ils sont encodés en en-têtes de cookie avec UTF-8;
- dans IE, la page de codes par défaut de la machine est utilisée (spécifique aux paramètres régionaux et jamais UTF-8);
- Firefox (et d'autres navigateurs basés sur Mozilla) utilisent seul l'octet de poids faible de chaque point de code UTF-16 (donc ISO-8859-1 est OK mais tout le reste est mutilé);
- Safari refuse simplement d'envoyer tout cookie contenant des caractères non ASCII.
dans la pratique, vous ne pouvez donc pas utiliser du tout de caractères non ASCII dans les cookies. Si vous souhaitez utiliser Unicode, des codes de contrôle ou d'autres séquences d'octets arbitraires, le cookie_spec vous demande d'utiliser un schéma de codage ad hoc de votre choix et de suggérer un codage URL (tel que produit par JavaScript encodeURIComponent
) comme un choix raisonnable.
En termes de normes réelles , il y a eu quelques tentatives de codification du comportement des cookies, mais aucune ne reflète jusqu'à présent le monde réel.
La RFC 2109 était une tentative de codification et de correction du cookie_spec Netscape d'origine. Dans cette norme, de nombreux autres caractères spéciaux sont interdits, car il utilise des jetons RFC 2616 (a y -
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, la gestion spéciale des chaînes entre guillemets et des échappements, ou les nouvelles fonctionnalités de cette spécification.
Le RFC 2965 a été une autre tentative, rangeant 2109 et ajoutant plus de fonctionnalités dans le cadre d'un schéma de «cookies de version 2». Personne n'a jamais mis en œuvre cela non plus. Cette spécification a les mêmes limitations de chaîne de jetons et de chaînes que la version précédente et c'est tout autant une charge de non-sens.
La RFC 6265 est une tentative de l'ère HTML5 pour éliminer le gâchis historique. Cela ne correspond toujours pas exactement à la réalité, mais c'est beaucoup mieux que les tentatives précédentes - c'est au moins un sous-ensemble approprié de ce que les navigateurs prennent en charge, n'introduisant aucune syntaxe censée fonctionner mais qui ne fonctionne pas (comme la chaîne citée précédente) .
Dans 6265, le nom du cookie est toujours spécifié comme RFC 2616 token
, ce qui signifie que vous pouvez choisir parmi les alphanums plus:
!#$%&'*+-.^_`|~
Dans la valeur du cookie, il interdit formellement les caractères de contrôle (filtrés par les navigateurs) et les caractères non ASCII (mis en œuvre de manière incohérente). Il conserve l'interdiction de cookie_spec sur l'espace, la virgule et le point-virgule, ainsi que pour la compatibilité avec tous les idiots pauvres qui ont effectivement mis en œuvre les RFC antérieurs, il a également interdit la barre oblique inverse et les guillemets, autres que les guillemets enveloppant la valeur entière (mais dans ce cas, les guillemets sont toujours considérés comme faisant partie de la valeur, pas un schéma de codage). Cela vous laisse donc avec les alphanums plus:
!#$%&'()*+-./:<=>?@[]^_`{|}~
Dans le monde réel, nous utilisons toujours l'original et le pire Netscape cookie_spec, donc le code qui consomme des cookies doit être prêt à rencontrer à peu près n'importe quoi, mais pour le code qui produit des cookies, il est conseillé de s'en tenir au sous-ensemble dans la RFC 6265.
;
caractère tant qu'il est entouré de guillemets doubles? En tant que tel:Set-Cookie: Name=Va";"lue; Max-Age=3600
Name="Va;lue"; max-age...
. Cela ne fonctionne pas dans les navigateurs et ce n'est pas autorisé dans la RFC 6265, qui est proposée pour remplacer 2965 et tente de refléter un peu mieux la réalité.1*<any CHAR except CTLs or separators>
et les séparateurs sont(
,)
,<
,>
,@
,,
,;
,:
,\
,"
,/
,[
,]
,?
,=
,{
,}
,SP
etHT
, donc les noms de cookies doivent être des caractères alphanumériques , plus!#$%&'*+-.?^_`|~
Dans ASP.Net, vous pouvez utiliser
System.Web.HttpUtility
pour coder en toute sécurité la valeur du cookie avant d'écrire dans le cookie et la reconvertir à sa forme d'origine lors de sa lecture.Cela arrêtera les esperluettes et équivaudra à des signes divisant une valeur en un groupe de paires nom / valeur lors de son écriture dans un cookie.
la source
Je pense que c'est généralement spécifique au navigateur. Pour être sûr, base64 code un objet JSON et stocke tout ce qu'il contient. De cette façon, il vous suffit de le décoder et d'analyser le JSON. Tous les caractères utilisés dans base64 devraient fonctionner correctement avec la plupart, sinon tous les navigateurs.
la source
La voici, en un minimum de mots . Concentrez-vous sur les personnages qui n'ont pas besoin de s'échapper:
Voilà comment vous répondez.
Pour les URL, le = a été conservé. L'intersection est évidemment sans.
Il s'avère que l'échappement se produit toujours et se produit de manière inattendue, en particulier dans un environnement de cookie Java où le cookie est entouré de guillemets doubles s'il rencontre les derniers caractères.
Donc, pour être sûr, utilisez simplement A-Za-z1-9. Voilà ce que je vais faire.
la source
Rfc6265 plus récent publié en avril 2011:
Si vous regardez @bobince répondre, vous voyez que les nouvelles restrictions sont plus strictes.
la source
vous ne pouvez pas mettre ";" dans le champ de valeur d'un cookie, le nom qui sera défini est la chaîne jusqu'au ";" dans la plupart des navigateurs ...
la source
Il existe 2 versions des spécifications des cookies
1. Cookies de la version 0 aka cookies Netscape,
2. Cookies de la version 1 aka RFC 2965
Dans la version 0 Le nom et la 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. , sinon utilisé avec des guillemets doubles
version 1 est beaucoup plus compliqué que vous pouvez vérifier ici
Dans cette specs version pour une partie de la valeur du nom est presque identique sauf le nom ne peut pas commencer par $ signe
la source
Il y a un autre problème intéressant avec IE et Edge. Les cookies dont le nom comporte plus d'une période semblent être supprimés en silence. Cela fonctionne donc:
alors que cela sera abandonné
la source
c'est simple:
Lien: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#Directives
la source
Encore une considération. J'ai récemment implémenté un schéma dans lequel certaines données sensibles publiées dans un script PHP devaient être converties et renvoyées sous forme de cookie crypté, qui utilisait toutes les valeurs de base64 que je pensais être garanties "en sécurité". J'ai donc crypté consciencieusement les éléments de données à l'aide de RC4, j'ai exécuté la sortie via base64_encode, et a heureusement renvoyé le cookie sur le site. Les tests ont semblé bien se passer jusqu'à ce qu'une chaîne encodée en base64 contienne un symbole "+". La chaîne a été écrite sans problème dans le cookie de la page. En utilisant les diagnostics du navigateur, j'ai également pu vérifier que les cookies ont été écrits inchangés. Puis, quand une page suivante a appelé mon PHP et a obtenu le cookie via le tableau $ _COOKIE, j'ai été balbutié pour trouver que la chaîne manquait maintenant le signe "+". Chaque occurrence de ce caractère a été remplacée par un Espace ASCII.
Compte tenu du nombre de plaintes non résolues similaires que j'ai lues depuis lors, décrivant ce scénario, citant souvent de nombreuses références à l'utilisation de base64 pour stocker "en toute sécurité" des données arbitraires dans des cookies, j'ai pensé signaler le problème et proposer ma solution certes délirante.
Une fois que vous avez effectué le cryptage que vous souhaitez effectuer sur une donnée, puis utilisé base64_encode pour le rendre "cookie-safe", exécutez la chaîne de sortie à travers ceci ...
Ici, je remplace simplement "+" (et j'ai décidé "=" également) par d'autres caractères "sans danger pour les cookies", avant de retourner la valeur codée à la page, pour une utilisation en tant que cookie. Notez que la longueur de la chaîne en cours de traitement ne change pas. Lorsque la même (ou une autre page du site) exécute à nouveau mon script PHP, je pourrai récupérer ce cookie sans manquer de caractères. Je dois juste me rappeler de transmettre le cookie via le même appel fix64 () que j'ai créé, et à partir de là, je peux le décoder avec l'habituel base64_decode (), suivi de tout autre déchiffrement de votre schéma.
Il pourrait y avoir un paramètre que je pourrais faire en PHP qui permette aux chaînes base64 utilisées dans les cookies d'être retransférées vers PHP sans corruption. En attendant, cela fonctionne. Le "+" peut être une valeur de cookie "légale", mais si vous souhaitez pouvoir retransmettre une telle chaîne à PHP (dans mon cas via le tableau $ _COOKIE), je suggère de retraiter pour supprimer les personnages offensants et les restaurer après la récupération. Il existe de nombreux autres personnages "sans danger pour les cookies" parmi lesquels choisir.
la source
Si vous utilisez les variables plus tard, vous constaterez que des éléments comme ceux-
path
ci laisseront passer les caractères accentués, mais ne correspondront pas réellement au chemin du navigateur. Pour cela, vous devez les saisir URIEncode. Donc, c'est comme ça:Ainsi, les caractères "autorisés" pourraient être plus que ce qui est dans la spécification. Mais vous devez rester dans la spécification et utiliser des chaînes codées par URI pour être sûr.
la source
Il y a des années, MSIE 5 ou 5.5 (et probablement les deux) avait un sérieux problème avec un "-" dans le bloc HTML si vous pouvez le croire. Bien qu'il 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 reste dans la base de données côté serveur.
la source
J'ai fini par utiliser
et
Cela semble fonctionner pour toutes sortes de personnages. J'ai eu des problèmes étranges autrement, même avec des caractères qui n'étaient pas des points-virgules ou des virgules.
la source