Разрешенные символы в 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, чтобы посмотреть все остальное в базе данных на стороне сервера.