Разрешенные символы в cookies

это по-быстрому:

каковы разрешенные символы в имени и значении cookie? Они такие же, как URL или какое-то общее подмножество?

Я спрашиваю, что я в последнее время какое-то странное поведение с помощью cookies, которые - в их имени, и мне просто интересно, если это что-то конкретное браузера или если мой код неисправен.

9 ответов


это по-быстрому:

вы можете подумать, что это должно быть, но на самом деле это совсем не так!

каковы разрешенные символы в имени и значении cookie?

согласно древнему Netscape cookie_spec весь NAME=VALUE строка:

последовательность символов, исключая двоеточие, запятую и Пробел.

так - должны работайте, и, похоже, все в порядке в браузерах, которые у меня есть; где у вас проблемы с этим?

по смыслу выше:

  • = законно включать, но потенциально неоднозначно. Браузеры всегда разделяют имя и значение на первое = символ в строке, поэтому на практике можно поставить = символ в значении, но не имя.

что не упоминается, потому что Netscape были ужасны при написании спецификаций, но кажется, постоянно поддерживается браузерами:

  • либо имя, либо значение может быть пустыми строками

  • если нет = символ в строке вообще, браузеры рассматривают его как cookie с именем пустой строки, т. е. Set-Cookie: foo это то же самое, что Set-Cookie: =foo.

  • когда браузеры выводят файл cookie с пустым именем, они опускают знак равенства. Так что Set-Cookie: =bar порождает Cookie: bar.

  • запятые и пробелы в именах и значениях действительно работают, хотя пробелы вокруг знака равенства обрезаются

  • управляющие символы (\x00 to \x1F плюс \x7F) не допускается

что не упоминается, и браузеры полностью непоследовательны, это символы, отличные от ASCII (Unicode):

  • в Opera и Google Chrome они кодируются в Cookie заголовки с UTF-8;
  • в IE используется кодовая страница машины по умолчанию (специфичная для локали и никогда UTF-8);
  • Firefox (и другие браузеры на базе Mozilla) используют низкий байт каждой кодовой точки UTF-16 самостоятельно (так что ISO-8859-1 в порядке, но все остальное искажено);
  • Safari просто отказывается отправлять файлы cookie, содержащие символы, отличные от ASCII.

поэтому на практике вы вообще не можете использовать символы, отличные от ASCII, в cookies. Если вы хотите использовать Unicode, управляющие коды или другие произвольные последовательности байтов, cookie_spec требует, чтобы вы использовали специальную схему кодирования по своему выбору и предлагали URL-кодирование (как произведено JavaScript encodeURIComponent) как разумный выбор.

С точки зрения фактический стандарты, было несколько попыток кодифицировать поведение cookie, но до сих пор ни одна из них фактически не отражает реальный мир.

  • RFC 2109 была попытка кодифицировать и исправить оригинальный Netscape cookie_spec. В этом стандарте многие другие специальные символы запрещены, так как он использует RFC 2616 токены (a - is еще разрешено), и только значение может быть указано в строке с кавычками с другими символами. Ни один браузер никогда не реализовывал ограничения, специальную обработку цитируемых строк и экранирование или новые функции в этой спецификации.

  • RFC 2965 была еще одна попытка, уборка 2109 и добавление дополнительных функций по схеме "cookies версии 2". Никто никогда не реализовывал ничего из этого. Эта спецификация имеет те же ограничения токенов и цитируемых строк, что и более ранняя версия, и это такая же ерунда.

  • RFC 6265 - это попытка эпохи HTML5 очистить исторический беспорядок. Он по-прежнему не соответствует реальности, но это намного лучше, чем предыдущие попытки-это, по крайней мере, правильное подмножество того, что браузеры поддерживают, не вводя синтаксис, который должен работать, но не работает (как и предыдущая цитируемая строка).

в 6265 имя файла cookie по-прежнему указывается как RFC 2616 token, что означает, что вы можете выбрать из алфавитов плюс:

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

в значении cookie он формально запрещает (отфильтрованные браузерами) управляющие символы и (непоследовательно реализованные) символы, отличные от ASCII. Он сохраняет запрет cookie_spec на космос, запятую и точка с запятой, плюс для совместимости с любыми бедными идиотами, которые фактически реализовали более ранние RFCs, он также запретил обратную косую черту и кавычки, кроме кавычек, обертывающих все значение (но в этом случае кавычки по-прежнему считаются частью значения, а не схемой кодирования). Так что оставляет вас с alphanums плюс:

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

в реальном мире мы все еще используем оригинальный и худший Netscape cookie_spec, так что код, который потребляет печенье должны быть готовы столкнуться довольно многое, но для кода, который производит куки, рекомендуется придерживаться подмножества в RFC 6265.


In ASP.Net вы можете использовать System.Web.HttpUtility чтобы безопасно кодировать значение cookie перед записью в файл cookie и преобразовать его обратно в исходную форму при чтении.

// Encode
HttpUtility.UrlEncode(cookieData);

// Decode
HttpUtility.UrlDecode(encodedCookieData);

это остановит амперсанды и знаки равенства, разбивающие значение на кучу пар имя/значение, когда оно записывается в cookie.


Я думаю, что это, как правило, браузер. Чтобы быть в безопасности, base64 кодирует объект JSON и сохраняет все в нем. Таким образом, вам просто нужно расшифровать его и проанализировать JSON. Все символы, используемые в base64, должны хорошо играть с большинством, если не со всеми браузерами.


новая rfc6265 опубликовано в апреле 2011 года:

cookie-header = "Cookie:" OWS cookie-string OWS
cookie-string = 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

Если вы хотите @bobince ответ вы видите, что новые ограничения еще более строгие.


вы не можете поместить "; "в поле значения файла cookie имя, которое будет установлено, является строкой до"; " В большинстве браузеров...


вот это в нескольких словах, как это возможно. Сосредоточьтесь на персонажах, которым не нужно бежать:

для печенья:

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

для urls

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

для cookies и URL (пересечение)

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

вот как вы ответите.

обратите внимание, что для cookies,= был удален, потому что он обычно используется для установки cookie значение.

для urls это = было сохранено. Перекресток, очевидно, снаружи.

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

оказывается, экранирование все еще происходит и неожиданное происходит, особенно в среде Java cookie, где cookie обернут двойными кавычками, если он сталкивается с последними символами.

поэтому, чтобы быть в безопасности, просто используйте A-Za-z1-9. Вот что я собираюсь сделать.


есть 2 версии спецификаций cookies
1. Версия 0 cookies aka Netscape cookies,
2. Версия 1 aka RFC 2965 cookies
В версии 0 имя и значение cookies являются последовательностями символов, исключая точку с запятой, запятую, знак равенства и пробелы, если они не используются с двойными кавычками
Версия 1 намного сложнее, вы можете проверить это здесь
В этой версии спецификации для name value part почти одинаковы, кроме name не могут начать с $ знак


Извините, я не мог добавить к принятому ответу, но я просто столкнулся с другой интересной проблемой с IE и Edge.

cookies, которые имеют имена с более чем 1 период, кажется, молча упал. Так Это работает:

cookie_name_a=valuea

в то время как это будет отброшено

cookie.имя.a=valuea


лет назад MSIE 5 или 5.5 (и, вероятно, оба) имели серьезную проблему с "-" в блоке HTML, если вы можете в это поверить. Хотя это не связано напрямую, так как мы сохранили хэш MD5 (содержащий только буквы и цифры) в файле cookie, чтобы посмотреть все остальное в базе данных на стороне сервера.