Пишу, по большей части, про историю, свою жизнь и немного про программирование.

Двухбуквенные домены и ИЕ

Про проблему с двухбуквенными доменами в браузере Микрософта знают наверное, очень многие. Если вкратце, считается, что на двухбуквенных доменах второго уровня «Эксплорер» не ставит куки.

Отчасти так оно и есть.

Сделано это вот для чего. Некоторые страны (например, Великобритания) запрещают регистацию домена второго уровня для своих нужд, домен должен находиться на третьем уровне в зоне специальных доменов второго уровня. Если бы я родился и жил в Лондоне, мой блог мог бы располагаться по адресу bolknote.co.uk.

Вот отсюда и родилось это ограничение — так как на домене третьего уровня в некоторых странах располагается куча чужих друг другу сайтов, они могли бы читать и писать куки друг друга через общий домен (и воровать данные авторизации, например), но браузеры не озаботились механизмом предотвращения этой угрозы.

В «Экплорере» (скорее всего это произошло в шестой версии) защиту устроили просто — если в домене второго уровня две буквы и он не располагается на домене общего назначения (.com, .net и т. п.), то это специальный домен из вышеописанного случая и ставить куку на него нельзя.

Но тогда как же, чёрт возьми, поступает «Яндекс» со своих двухбуквенным «ya.ru»? Есть какая-то особая магия?

Разочарую — её нет, есть исключения.

Ребята из «Микрософта» через какое-то время поняли, что проверять домен на двухбуквенность — плохая идея, оказалось, что существуют двухбуквенные домены без специального значения и специальные домены с другим количеством букв (например — географические домены). Пришлось встроить в браузер список исключений, найти его можно по урлу res://urlmon.dll/ietldlist.xml.

Список исключений в IE (41.52КиБ)

Т. е. если домен встречается в теге «tld» или содержит только две буквы на втором уровне, то куку ставить нельзя, но если он встретился в теге «domain» — то можно. Посмотрите на скриншот, домен «Яндекса» содержится в списке исключений. Естественно, список может меняться при обновлении браузера.

Остальным браузерам так же приходится решать эту проблему. Например, ФФ содержит примерно такой же список:

# примерное количество значений в этом списке у ФФ:
bolk@Bolk ~  $ grep -aF chel.ru /Applications/Firefox.app/Contents/MacOS/XUL  |  strings | fgrep . | fgrep -v / | sort -u | wc -l
   4019

# двадцать последних (по алфавиту) значений:
bolk@Bolk ~  $ grep -aF chel.ru /Applications/Firefox.app/Contents/MacOS/XUL  |  strings | fgrep . | fgrep -v / | sort -u | tail -20
z.bg
z.se
za.com
za.net
za.org
zachpomor.pl
zagan.pl
zakopane.pl
zaporizhzhe.ua
zarow.pl
zgora.pl
zgorzelec.pl
zgrad.ru
zhitomir.ua
zj.cn
zlg.br
zoological.museum
zoology.museum
zp.ua
zt.ua

Не знаю все ли четыре тысячи относятся к обсуждаемому списку (кстати, в нём всего 133 российских домена), но такой список точно существует.

Тот же список есть и в «Хроме» (на моём «Маке» он содержится в файле «Google Chrome Framework» и состоит из более 3,5 тысяч значений), в «Сафари» ничего похожего я обнаружить не смог, то ли такого механизма там нет, то ли спрятано глубже, чем мне позволяет искать моя лень. «Опера» держит свой список в файле «public_domains.dat», в нём на настоящий момент 4291 значение.

Таким образом, если вы владелец двухбуквенного домена и вам не повезло, у вас не работают куки как положено, пишите на адреса техподдержки производителей браузеров, а пока делайте редирект на домен третьего уровня (например, на «www»).

28 комментариев
Виталий 2012

Для этих целей существует список Public Suffix List ( http://publicsuffix.org/learn/ ), на который, как утверждается, ориентируются Mozilla, Chrome и Opera.

Виктор 2012

Комментарий для Виталий:

Что-то я не нахожу домен hh.ru :)

Евгений Степанищев (bolknote.ru) 2012

Комментарий для Виталий:

Видимо, они его с разной скоростью в браузерах обновляют.

Евгений Степанищев (bolknote.ru) 2012

Комментарий для Виталий:

В этом списке почти 6 тысяч доменов.

Евгений Степанищев (bolknote.ru) 2012

Комментарий для Виктор:

Что-то я не нахожу домен hh.ru :)

Видимо они не заморачиваются с установкой кук на корневой домен:

bolk@Bolk ~  $ telnet hh.ru 80
Trying 94.124.200.86...
Connected to hh.ru.
Escape character is ’^]’.
GET / HTTP/1.0
Host: kazan.hh.ru

HTTP/1.1 200 OK
Server: nginx/1.2.0
Date: Tue, 17 Jul 2012 19:35:34 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 61518
Connection: close
Set-Cookie: hhrole=anonymous; Path=/
Set-Cookie: unique_banner_user=1342553734.358669954861416; expires=Wed, 18 Jul 2012 19:35:34 GMT; Path=/
Set-Cookie: unique_banner_user=1342553734.351531650608922; expires=Wed, 18 Jul 2012 19:35:34 GMT; Path=/
Expires: Tue, 17 Jul 2012 19:35:33 GMT
Cache-Control: no-cache
X-Request-ID: ab1f4b6b1d93688e17e7bbcfb46f1bfb

Виталий 2012

Комментарий для Евгения Степанищева:

Да, нерегулярно. Вот к примеру лог изменений этого списка в Chromium http://src.chromium.org/viewvc/chrome/trunk/src/net/base/effective_tld_names.dat?view=log

Последнее изменение датируется 2 ноября прошлого года

Виталий 2012

То же, для Mozilla. http://hg.mozilla.org/mozilla-central/log/ba8463beab13/netwerk/dns/effective_tld_names.dat
Тут все выглядит получше.

Павел (blog.ad.by) 2012

Спасибо, интересная информация. Правда, с современной точки зрения голый домен — это пережиток прошлого, префикс www всегда будет нужен в обозримом будущем. Так что не вижу смысла писать разработчикам.

SunChaser (sunchaser.info) 2012

Комментарий для blog.ad.by:

голый домен — это пережиток прошлого

ээ почему вы так считаете?

Andrey Nikanorov 2012

Комментарий для blog.ad.by:

Вот мне тоже интересно, про «пережиток прошлого». Я бы сказал, что www — пережиток. Да и зачем он нужен то?

shaltai-boltai 2012

Интересно, сами-то британцы довольны таким запретом? Хотели как лучше.. и сами же учинили нехилый бардак на этом втором уровне.

Зачем, спрашивается, из-за странных людей усложнять жизнь всем остальным?

Данила 2012

Проблемы со _ВСЕМИ_ двухсимвольными доменами есть только в IE. Остальные браузеры, ориентируясь на Public Suffix List не имеют особой проблемы, потому что запрещают ставить только на действительно публичные домены (вроде pp.ru или т. н. «геодоменов», вроде e-burg.ru). Собственно, поэтому они и не очень часто обновляются — там мейнтейнится список запретов, а не исключений.

Что касается «IE не ставит» — это тоже не совсем так. Он не ставит куку, если видит заголовок Set-Cookie с явно указанным «запретным» domain. И прекрасно ставит, если domain не указан, более того — в нарушение стандарта эту же куку показывает на всех субдоменах.

Евгений Степанищев (bolknote.ru) 2012

Комментарий для shaltai-boltai:

Зачем, спрашивается, из-за странных людей усложнять жизнь всем остальным?

Не только британцы этим страдают. Минимум три домена — uk, us и nl. nl вообще один из первых национальных доменов, возможно тогда так принято было.

Евгений Степанищев (bolknote.ru) 2012

Комментарий для Данила:

Проблемы со всеми двухсимвольными доменами есть только в IE.

Нет в IE проблем со всеми доменами, я об этом целую заметку написал.

Остальные браузеры, ориентируясь на Public Suffix List не имеют особой проблемы, потому что запрещают ставить только на действительно публичные домены (вроде pp.ru или т. н. «геодоменов», вроде e-burg.ru). Собственно, поэтому они и не очень часто обновляются — там мейнтейнится список запретов, а не исключений.

Нет, это не так. Исключения там тоже есть. Они начинаются с восклицательного знака, например:

*.ar
!congresodelalengua3.ar
!educ.ar
!gobiernoelectronico.ar
!mecon.ar

Что касается «IE не ставит» — это тоже не совсем так. Он не ставит куку, если видит заголовок Set-Cookie с явно указанным «запретным» domain.

Где-то можно прочитать про чьи-нибудь эксперименты на эту тему?

Евгений Степанищев (bolknote.ru) 2012

Комментарий для Данила:

Он не ставит куку, если видит заголовок Set-Cookie с явно указанным «запретным» domain.

Сомневаюсь, что это так. Иначе неясно с чего бы «Яндекс» указывал домен на ya.ru:

HEAD / HTTP/1.1
Host: ya.ru

HTTP/1.1 200 Ok
Server: nginx
Date: Wed, 18 Jul 2012 04:58:34 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 4193
Connection: close
Cache-Control: no-cache,no-store,max-age=0,must-revalidate
Expires: Wed, 18 Jul 2012 04:58:34 GMT
Last-Modified: Wed, 18 Jul 2012 04:58:34 GMT
P3P: policyref=«/w3c/p3p.xml», CP=«NON DSP ADM DEV PSD IVDo OUR IND STP PHY PRE NAV UNI»
Set-Cookie: yandexuid=6413745831342587514; Expires=Sat, 16-Jul-2022 04:58:34 GMT; Domain=.ya.ru; Path=/

Данила 2012

Для лучшего понимания контекста — я тот человек, по вопросу которого на хабре ты эту запись написал.
В оригинальном вопросе на хабре ( http://habrahabr.ru/qa/21647/ ) как раз немного обсуждается, как оно работает.

Нет в IE проблем со всеми доменами, я об этом целую заметку написал.

Ок, со всеми двухсимвольными, кроме исключений.

Нет, это не так. Исключения там тоже есть. Они начинаются с восклицательного знака.

Насколько я понимаю, они начинаются с восклицательного знака, отменяя наложенное ранее «широкое» правило из этого же списка.
Т. е. СНАЧАЛА *.ar — все домены второго уровня в TLD ar объявляются «публичными» (куку не ставить), а потом !educ.ar — отменяет это правило. Т. е. это не «исключения», о которых я говорил. Public Suffix List содержит список «куда не ставить» и браузеры, которые им пользуются — не имеют других соображений о том «куда не ставить», в отличие от IE.

Где-то можно прочитать про чьи-нибудь эксперименты на эту тему?

Можно в комментариях мои слова прочитать — у меня как раз пара двухсимвольных доменов есть.
Да собственно можешь сам попробовать —  http://66.ru/test/iframe/index.php ифреймы показывают текущие куки, а  http://66.ru/test/iframe/index.php?set=bolk попробует поставить куку в разных вариантах. Можно так же позаходить на  http://www.66.ru/test/iframe/index.php и  http://other.66.ru/test/iframe/index.php и попробовать поставить куки оттуда разными браузерами.

Сомневаюсь, что это так. Иначе неясно с чего бы «Яндекс» указывал домен на ya.ru:

Яндекс указывает домен на .ya.ru (на не на ya.ru) потому что ya.ru в списке исключений IE и работает как любой другой домен.

Данила 2012

В «Экплорер» (скорее всего это произошло в шестой версии) защиту устроили просто — если в домене второго уровня две буквы, то это специальный домен из вышеописанного случая и ставить куку на него нельзя.

Кстати говоря, эта логика со времен шестого эксплорера довольно заметно изменилась — например в .gr и .pl современный IE соглашается ставить куки на любой двухсимвольный домен второго уровня.

Данила 2012

А, нет, я слегка приврал. Логика не менялась со времени IE5. В IE8 добавили как раз список исключений.

Повторю лучше ссылку, которую уже постил на хабре — там всё про IE очень подробно написано.

http://blogs.msdn.com/b/ieinternals/archive/2009/09/19/private-domain-names-and-public-suffixes-in-internet-explorer.aspx

Евгений Степанищев (bolknote.ru) 2012

Комментарий для Данила:

Ага, спасибо за ссылки, буду экспериментировать как только найду где-нибудь IE.

Евгений Степанищев (bolknote.ru) 2012

Комментарий для Данила:

Яндекс указывает домен на .ya.ru (на не на ya.ru) потому что ya.ru в списке исключений IE

В списке исключений он ведь только с восьмой версии. А есть ещё шестая и седьмая.

Евгений Степанищев (bolknote.ru) 2012

Комментарий для Данила:

Странно ещё, что логика не должна была меняться с пятого по шестой IE, но при этом есть вот такая ссылка: http://support.microsoft.com/default.aspx?scid=kb%3BEN-US%3B310676 где говорится о проблемах с шестой версией.

Данила 2012

Комментарий для Евгения Степанищева:

В списке исключений он ведь только с восьмой версии. А есть ещё шестая и седьмая.

Судя по всему, Яндекс положил болт. В шестом IE при заходе на ya.ru — кука на ya.ru не ставится.

Евгений Степанищев (bolknote.ru) 2012

Комментарий для Данила:

Ага, понятно.

Я поспрашивал ребят из «Яндекса», но найти того, кто владеет информацией про короткий домен непросто (в смысле на какой браузер забили).

ul.tvoridob.ro 2012

А еще есть vk.com, 6-го IE только под рукой нет чтобы проверить :)

Евгений Степанищев (bolknote.ru) 2012

Комментарий для http://ul.tvoridob.ro:

У меня нет знакомых во «Вконтакте».

Данила 2012

А еще есть vk.com, 6-го IE только под рукой нет чтобы проверить :)

к .com это не относится.

twitter.com/thenameisbusy 2012

Комментарий для Данила:

Прощу прощения, промахнулся.

В Сафари под виндой есть файл
C:\Program Files\Safari\Safari.resources\TopLevelDomains.plist

расшарил, кому интересно -​-​
https://docs.google.com/open?id=0BzMtX0bMEVdpb1J6ZmQxTlJ0Y0U

Евгений Степанищев (bolknote.ru) 2012

Комментарий для http://twitter.com/thenameisbusy:

Ага, нашёл такой файл на «Маке», спасибо. Вот тут хранится:

/System/Library/PrivateFrameworks/Safari.framework/Versions/A/Resources/TopLevelDomains.plist