New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
IDN домены (в т.ч. кириллица) #194
Comments
Тут вот в чём дело. Кириллицы вообще не должно быть. Домен — это ascii-символы и если сервер отдаёт именно кириллицу, то это ошибка. Поэтому вначале нужно копать в сторону phpinfo() и что отдает $_SERVER. |
Да, домен вроде бы нормально формируется. Тогда есть два раздельный направления. Я подскажу, а вы уже проверите. Ошибка Disallowed Key Characters, как вы и написали в Второй момент — установка куки через js, как вы написали в |
Вы имеете ввиду в Input.php? Думаю, что вначале нужно с ней разобраться. |
В openserver не пробовали на русском домене проверить работу? |
Проверил, как и просили, переменную $str в файле |
Тут непонятно как тестировать и искать ошибки. Если куку кто-то ставит, то нужно определять кто именно. От этого и плясать. Теоретически проверку в |
На самом деле проблему решает применение моих патчей из первого сообщения. Для старых версий ветки 0.8х следует исправить недостаточную фильтрацию |
Я понимаю, но эти патчи могут негативно сказаться на тех, у кого нормальные домены. Тем более это может повлиять на уровень безопасности системы. Нужно искать вариант как всё это оттестировать и уже после исправлять код. |
Нормальные домены - это те, которые стандартизированы ICANN, в них входит и кириллица и иероглифы и диакритические костыли европейских языков. Предлагаю всё же использовать термин IDN и всё же использовать стандартное преобразование punycode, где это возможно. То есть: пункты 1 и 3 не влияют на безопасность точно. По факту этому багу много лет, странно, что не вылез раньше. |
Нормальные домены, это те, которые не требуют никакого преобразования для корректной работы. Всё остальное — это «хак». Далее. У вас ситуация обратная. Обычно проблема в том, что адрес идет ASCII, а нужно получить кириллицей. Здесь наоборот. Если говорить о PHP, то для этого есть специальные функции
Если это js-код, то проблема с взаимодействием с браузером (именно он отдает Что касается относительных путей, то это даже не буду обсудать. Только абсолютный путь. Всё это можно решить только после тестирования. Ваши решения «в лоб», не факт, что будут корректно работать у других. Может так сервер настроен, может браузер и т.д. Это слишком серьёзные изменения, чтобы их внедрять без тестирования и вообще, нормальной реализации. |
Соглашусь только по части хака - это второй пункт, да мы вносим изменения в файлы Codeigniter. По доменам же, вы мягко говоря неправы и я вынужден переадресовать к документации:
Далёк от мысли, что стандартная установка из коробки может давать такие ошибки, у нас много серверов построенных так, а проблемы только с Codeigniter и Maxsite. Скорее здесь проблема на стыке браузер-javascript. Потому как реализация Chromium таких ошибок не даёт. Вполне возможно, Codeigniter в используемой версии вышел так давно, что IDN тогда был только в проекте...
Конечно нет! Не я писал этот код и не могу знать, почему и где допущена ошибка фильтрации. Путь для исправления я описал выше (используем библиотеку punycode), но видимо по невнимательности или глупости не могу найти где это исправить. Подозреваю, что если найти и исправить этот баг - не придётся вносить изменения в допустимые символы
На мой взгляд, статус ошибки обнаруженной мной ошибки - критический. Это как-никак недостаточная фильтрация и крах системы для пользователей всех браузеров кроме Chromium. В целом, я сказал всё, что хотел - имеющий руки и голову себе на сайте поправить сможет, а исправлять ли ошибки в общей версии - решайте по своему разумению. |
Боюсь, что вы не до конца понимаете как это работает. Все домены должны быть в ASCII-формате. Для того, что бы обеспечить поддержку non-ASCII, используется «хак», а именно префикс Поскольку кука — это часть заголовка http-запроса, то проблема на уровне взаимодействия с браузером. На уровне сервера проблем с кодированием нет. По В То что вы сделали — это конктерно ваш частный случай. В одном случае вы отключили проверку, в другом, убрали путь. Если бы браузер отправлял данные в ASCII-формате, то таких проблем не будет. И, строго говоря, так оно и должно быть, хотя бы из принципа обратной совместимости. Если в одном браузере всё работет, а в другом нет, то вывод напрашивается сам собой где нужно искать проблему. Лично я не пользуюсь кирилическими доменами, поэтому у меня нет возможности даже воспроизвести данную проблему. Придумайте способ поднять кириллический домен на OpenServer (https://ospanel.io/docs/ — у меня почему-то не получается), тогда мы сможем приступить к конкретному разговору. |
Я тоже сталкивался с ошибкой Disallowed Key Characters из-за jquery.cookie.js. |
Вы можете исправить регулярку и проверить её работу? |
дак проверил уже давно |
В общем в 0.96 в файле system/core/Input.php строку 746: и проблем с encodeURI и encodeURIComponent не будет. |
Поправил предыдущие два сообщения, там съедались символы в регулярке. |
Вообще-то, коллеги, то, что вы обсуждаете изложено в моих комментариях выше и даже включено в мой патч. |
iachaly насколько я вижу, у вас там не решение проблемы, а костыли. |
Да, мне тоже кажется, что с символом % более элегантное решение. Кука может именоваться с этого символа? |
Вот к примеру кука выведенная по print_r: В данном случае в начале идет английский символ, т.к. домен используется английский и поэтому сработал только encodeURIComponent. |
Во-первых ваше решение это абсолютно такой же костыль - внесение изменений в систему CI. Но без него никак, тут я согласен. Можно конечно переопределить метод, но это повлечёт корректировки по всему Maxsite. |
Кука с процентами - плохое решение, поскольку в три раза увеличивает её длину. Можно вылететь за пределы стандарта и получить ошибку. |
iachaly исправление регулярки это не костыль, а исправление ошибки. И если не хотите поправить регулярку, как я уже сказал не используйте никогда encodeURI и encodeURIComponent и тогда тоже ничего править не придется. |
Кто же спорит, только оно не должно туда попадать в принципе (как и любые другие символы кроме латиницы). Если по хорошему, туда должен быть встроен конвертер пуникода, аналогично моему решению с библиотекой javascript. |
iachaly вот как раз наоборот, знак процента туда должен попадать, т.к. он есть в стандарте и его используют стандартные функции encodeURI и encodeURIComponent. Смотрите ASCII таблицу: И как я сказал, в данном случае регулярка не правильная. |
Не спорьте. :-) Вот есть документация: https://developer.mozilla.org/ru/docs/Web/HTTP/Headers/Set-Cookie
Символа процента нет, значит ошибка именно в CodeIgniter, который слишком жестко фильтрует данные. |
Да, так и сделаю. |
Подтверждаю наличие ошибки |
На каких адресах появляется ошибка? |
При входе в админку, через несколько кликов, отследить конкретную страницу не получается. Но есть ощущение, что переполнение происходит раньше, на страницах сайта. На самом деле, надо просто привести файлы CI и Maxsite к соответствию стандарту, правда, я уже устал отлавливать то место, где система разваливается, дальше показанного на скриншотах продвинуться на могу (я всё же не тестировщик). Патченные файлы приложены ещё в мае, собрал и для 98 версии, чем они не устраивают? |
Ваш патч не годится по той простой причине, что он исправляет следствие, а не причину. Проблема в фильтрации CodeIgniter, который считает, что существуют недпустимые символы, и их нужно жестко «рубануть». Сложность в том, что нет информации по тому какие имена кук вообще допустимы. Либо это самодурство CodeIgniter, либо они на чем-то основывались. Я могу предложить вариант, вообще убрать (закоментировать) строчки:
в файле Input.php. Но насколько это повлияет на безопасность совершенно непонятно. С моей точки зрения этот код написан в доюникодовскую эпоху, а значит нужно прописать регулярку так, чтобы она поддерживала все символы юникода. |
Уважаемый HaipaiUser находил в стандарте процент, его добавили с появлением IDN-доменов. Комментировать эту строку уж точно не следует на мой взгляд, это полностью лишит систему фильтрации. Поддерживать все символы юникода в общем и не надо. ICANN героически решила проблему, которую создали, привязав по глупости или злому умыслу DNS и интернет к латинице: у них есть документ, перечисляющий допустимые символы, плюс соответствие их в punycode. Также продублирую из шапки темы: можно записать регулярное выражение в следующем виде: Другое дело, что это не исправляет ситуацию с быстрой загрузкой (закинул этот баг в профильную тему, там разбираться не так просто, как здесь). З.Ы.: не ответил по существу - причина на мой скромный взгляд в общем в существовании доменов IDN и ошибках в проектировании сети интернет, привязка к латинице. Поэтому и появляются символы в куках, которых якобы не должно там быть. Punycode это ведь в общем грязный хак, который в угоду барышам решили внедрить повсеместно. CI2 появился до повсеместного его распространения. А прикладываемые мной файлы - единственный способ это исправить. Они и есть та точка отказа, остальное находится вне CI и Maxsite. |
Понятно, что всё не так просто. :) Кука — это http-заголовок и почти все браузеры (кроме старых сафари вроде бы) отправляют данные в юникоде. То есть использование юникода и прочих спецсимволов вообще не проблема и именно поэтому кука может именоваться как угодно. Ни на одном этапе проблемы не возникает. То есть её фильтрует CodeIgniter, и вообще непонятно зачем это делается. Если это неверное имя, то кричать должен либо сервер, либо браузер. Все данные, которые идут от пользователя (post или куки) всё равно ещё раз фильтруются при использовании. Поэтому я думаю, то отключение вряд ли на что-то повлияет, хотя 100% гарантии дать не могу. В новых версиях CodeIgniter такй проверки нет. Только прогоняется на xss-фильтрацию (полноценно еще не изучал). |
Еще момент, не сообразил сразу написать. В jquery.showhide.js можно попробовать кодировать window.location.host с помощью encodeURIComponent:
Тогда дополнительные библиотеки в виде Punycode не нужны. |
Да, на старых версиях этого было достаточно и я даже выкладывал исправленный файл, где не тупо резалось, а кодировалось в пуникод. Раньше эта библиотека почему-то вызывала падение некоторых javascript. Если нужно - могу поискать. Дело в том, что в новых версиях этого хватать перестало, и меня ввело в ступор такое поведение сервера... По поводу фильтрации на уровне сервера - на мой взгляд нужно вообще фильтровать всё, что приходит от недоверенного источника. С другой стороны кука всё равно прогоняется через фильтры и кодировщики, и нелатинские символы превращаются в коды наподобие такого: %2A%3F%1C где каждая тройка - нужный нам код. Видимо процент в стандарте по кукам появился вот ради этого. Но кстати, один из маркеров того, что здесь всё нечисто - отваливающиеся скрипты, использующие куки, например загрузка аяксом (в котором портится путь к аяксу в переменной maxsite). Что ещё более удивительно - данная проблема есть в firefox, но отсутствует в chromium. Ещё весной об этом писал) |
Аякс — это отдельная песня. Там нужно разбираться и там довольно сложная завязка на php-функции преобразования адреса. А вот что касается jquery.showhide.js, то вроде бы encodeURIComponent будет достаточно, чтобы не вылезти за границы допустимых символов. |
Поправка, для jquery.showhide.js в первом архиве с патчем лежит и библиотека punycode и патченный файл. Лучше всё же его, правильнее адрес всё же кодировать, а не просто обрезать. По аяксу ошибка в кодировании переменной ajax. Если по хорошему - надо её на уровне системы прогонять через преобразователь в punycode. |
C аяксом немного проще. Для js адрес нужно отдавать в юникоде, то есть без idn-преобразования. У нас же он отдается как $MSO->config['site_url'], то есть от $_SERVER, ге это преобразование уже выполнено. Таким образом проблема здесь только в том, чтобы выполнить обратное преобразование в юникод. В php для этого есть функция |
На вскидку приходит простое решение. Для таких случаев можно предусмотреть в MaxSite CMS в конфигурационном файле явное указание адреса сайта. Для аякса, где только и требуется данная настройка, если адрес задан, то он и будет использоваться. Иначе как сейчас — автоматом. Это не идеальное решение, но хотя бы рабочее. |
В общем вот предварительное решение. В конец файла common.php нужно добавить функцию
В верху в функци getinfo() исправить часть с ajax чтобы получилось так:
После этого аякс должен работать. |
Сейчас тестирую, вроде всё идёт нормально. Предложенное решение выше работает. Даже заработал аякс в админке. Пару дней надо посмотреть как оно под нагрузкой поработает, какие отзывы будут. А вообще мы с коллегами пришли к неутешительному выводу: везде, где явно или неявно появляются IDN нужно приводить к нужному виду аналогичными функциями, иначе обречены затыкать дыры в порядке баг-репортов пользователей. Сейчас этих места два: клиентский JS и серверный PHP. Нужно делать это централизованно, но вот вопрос, где? |
Ну насчет дыр это вы погорячились. :-) Обычные технчиеские проблемы, которые просто сложно выявить и оттестировать. Поскольку сейчас уже разобрались, то ясно, что домен для JS должен отдаваться в юникоде через encodeURIComponent. На уровне PHP адрес определяется в IDN-формате, что не соответствует юникоду. Поэтому для передачи адреса из PHP в JS мы и используем кодирующую функцию. И здесь только одна точка — это аякс-адрес. |
Дыры не в смысле безопасности, это ведь в общем следствие меняющихся стандартов... В настройке веб-серверов до сих пор используется (и будет) явное указание домена в пуникоде. Никакого кодирования там не поддерживается и нативный адрес это как раз Добавлю: с этим изменением за последние дни не наблюдается проблем в работе сайтов на ИДНках, жизнеспособно и стабильно. Нагрузку тоже не заметил. |
Ок. Тогда немного доработаю и внесу изменения в систему. |
В данной теме будет собрана информация по работе Maxsite с IDN-доменами, например на кириллице. Проблема тянется ещё с давних времён и касается скорее особенностей работы CodeIgniter с Cookie и особенностей Javascript, jQuery, Ajax. Для меня всё продолжилось с появления новых сайтов на подобных доменах, что сразу выявило несколько проблем:
cookieName : ( punycode.toASCII(window.location.host) + window.location.
/system/core/Input.php
в строке 746 было исправлено регулярное выражение следующим образом:preg_match("/^[a-z0-9:_\/-]+$|/i", $str)
. На самом деле я не знаю, насколько это понизило безопасность системы, однако альтернатива такому решению - исправлять все подсистемы javascript с неизвестным заранее результатом. Подчеркну однако, что проблема кроется именно в неправильной подстановке Cookie!/application/maxsite/admin/plugins/admin_page/all-files-update-ajax.php
через Ajax в файле/application/maxsite/admin/plugins/admin_page/all-files.php
Важно, что при обращениях, браузер распознаёт пути в кодировке ISO-8859-1, то есть кракозябры другие. Для решения пришлось отказаться от вызова скрипта по абсолютному пути. Вообще я противник использования абсолютных путей на сайте, и это было для меня очевидным решением в случае неправильного кодирования как раз имени хоста. В указанном файле 3 вызова скрипта, и убрал константу getinfo('ajax') вот так:
'/ajax/' . base64_encode('admin/plugins/admin_page/all-files-update-ajax.php');
Данное решение не будет работать, если система находится не в корне домена, а в подпапке, но для меня это было неважно. Проблема возникает, как мне кажется, из-за того, что при различном кодировании кириллицы браузер может признавать разные варианты как различные домены - вот почему предложенное решение помогло.P.S. Не ругайте, если что-то неверно оформил, только начал изучать GitHub. Кроме того, прошу прощения за всё-же очень костыльные решения данных проблем. Надеюсь более толковые коллеги предложат более правильные решения. Прикладываю файлы, на которые ссылаюсь в архиве: chaly-maxsitepatch.zip
UPD0. Ранее выкладывал решение и не добавил его в шапку. Регулярное выражение в следующем виде:
preg_match("/^[a-z0-9а-я:_\/-]+$/iu", $str)
.UPD1. Уважаемый HaipaiUser предложил изменить регулярное выражение следующим образом:
preg_match("/^[a-z0-9%:_\/-]+$/i", $str)
. Результат тестирования:Мнение iachaly: кука с процентами - плохое решение, поскольку в три раза увеличивает её длину. Можно вылететь за пределы стандарта и получить ошибку.
Данный хак добавлен в систему: ac5cb78
The text was updated successfully, but these errors were encountered: