| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > PHP: Общие вопросы > XSS Link Cleaner |
| Автор: kat_ru 4.3.2008, 15:44 | ||
| Насколько актуальна функция ниже? Критика, пожелания, что можно или нужно изменить - исправить? Если не сложно как? Заранее благодарен за ответ.
|
| Автор: A1ekcandr 4.3.2008, 15:51 |
| зачем столько strpos в этом случае сделть легче через регулярное выражение |
| Автор: mishaSL 4.3.2008, 16:44 |
| Согласен c A1ekcandr, проще через 1 регулярное выражение. |
| Автор: GeneralElectric 4.3.2008, 16:51 |
| Непонятно, зачем такой большой набор символов. Вообще, было бы неплохо, если автор словами сформулировал задачу, которую он хочет решить. В таких вопросах всегда полезно это делать, поскольку толкование XSS уязвимости у всех может быть разным. |
| Автор: kat_ru 4.3.2008, 17:42 | ||
Например так?
GeneralElectric Избавить адресную строку от ненужных символов... Хотя наверно проще и надежней сделать список только разрешенных символов. |
| Автор: kat_ru 5.3.2008, 01:45 | ||
У меня с регулярками туго... ((( Не понимаю и писец... Перечитывал уже раз 10 на php.net Если не сложно можете по символьно объяснить логику вот этого выражения: " |^[a-z 0-9\\.:_-/]+$|i " |
| Автор: SelenIT 5.3.2008, 03:36 | ||||
| - открывающий ограничитель шаблона ^ - начало строки [ - начало символьного класса, допускающего: a-z - лат.буквы - пробел (не понимаю только, нафига он в урле — по-моему, он лишний) 0-9 - цифры (можно написать короче - \d) \\ - обратный слеш (заэкранирован, чтобы PHP не подумал, что это заэкранированная точка. Кстати, в урле обратный слеш, имхо, тоже не нужен) . : _ / - любой из этих символов - - вообще-то, между символами внутри квадратных скобок задает диапазон символов. Но в данном случае начало диапазона (_ - 0x5F) находится в кодовой таблице раньше его конца (/ - 0x2F), поэтому, судя по http://www.php.net/manual/ru/reference.pcre.pattern.syntax.php
] - конец символьного класса + - означает, что входящие в класс символы могут встречаться один и более раз $ - конец строки. | - закрывающий ограничитель шаблона i - http://www.php.net/manual/ru/reference.pcre.pattern.modifiers.php, указывающий на независимость от регистра Все вместе означает, что строка должна от начала до конца состоять из ненулевого количества символов, перечисленных в классе, без учета регистра букв. |
| Автор: source777 6.3.2008, 00:27 | ||||||
kat_ru, общий смысл |^[a-z 0-9\\.:_-/]+$|i состоит в том, чтобы проверить, что URL состоит из латинских букв, цифр, пробелов, точек, значков подчёркивания, дефисов, двоеточий, прямых и обратных слешей. Ещё более мощным решением будет вырезать из URL все символы кроме вышеобозначенных, тогда сайт даже не заметит, что была попытка ввести какие-то иные символы... P.S. Поскольку я уже отчаялся добиться от этого форума вменяемой работы, то смотри вложение, надеюсь хотя бы его форум не испаганит... Код там 100%-рабочий вместе с большим комментарием... |
| Автор: Хрипа 6.3.2008, 10:25 | ||||
Я делаю так:
Если у вас уже готовый скрипт то интегрировать можно так:
|
| Автор: solenko 6.3.2008, 11:00 |
| А смысл в такой фильтрации на входе? Фильтровать нужно: 1. На этапе вставки в базу (от того, тчо может вызвать креш базы) 2. На выводе данных (от всего, чего мы не ждем в выводе) А то как-то сомнительна практическая ценность получается. 1. Как сохранить html (это нужно практически в каждом проекте)? 2. Вы расчитываете, что в базе у вас корректные данные, т.к. вы их туда вставили. Но вы забываете, что отдаете проект заказчику. И он может, например, импортировать данные в базу минуя ваши фильтры. |
| Автор: flashaa 6.3.2008, 11:46 |
| Согласен с Solenko. Просто фильтровать URL вот так - пытаться убить конкретных людей с помощью выброса атомной бомбы на целую страну. Не проще ли отфильтровать те параметры, которые надо отфильтровать а не пускать все под общую гребенку? К тому же если захотим вдруг пропустить фильтруемые символы, придется отключать эту фильтровалку и писать отдельно под каждый запрос (что и надо было делать). |
| Автор: SelenIT 6.3.2008, 12:54 |
В квадратных скобках точку экранировать не надо. Сорри, прошу доказательств. Желательно не через браузер (который любезно сам заменяет пробелы на %20 при сабмите), а в виде скриншота сессии телнета. |
| Автор: kat_ru 6.3.2008, 14:07 | ||||||
предположим на страничке есть <div id="main"></div> в случае если зайти на страничку по такой ссылке: http://host/?a=<script>getElementById('main').innerHTML=XSS Here!</script> то это и будет XSS.
Для POST данных нужен немного другой подход... ибо каждая форма имеет свой обработчик. А например mysql_escape_string (кстати: mysql_real_escape_string) не сработает и даже выведет ошибку в случае если нет активного соединения с БД...
строка "header("location: ".$NQString."", true, 301);" 301 Статус заголовка HTTP скажет поисковикам например, что страница переехала окончательно и накопленный рейтинг надо бы перенести на $NQString. Ведь если на множество форумов распространят ссылку http://host/?a=<script>getElementById('main').innerHTML="XSS Here!";</script> то это цитируемость страницы... которая переместиться на http://host/? Поправьте если не прав... Спасибо всем! Думаю вопрос решен... |
| Автор: SelenIT 6.3.2008, 14:24 | ||||
Да ну? Яваскрипт из адресной строки может выполниться в одном случае - по "ссылке" с "протоколом" javascript:. Другое дело, если в коде страницы где-то вызывается echo $_GET['a'] без проверки (например, перед результатами поиска отображается сама поисковая фраза) - тогда да, возможностей "творчески переосмыслить" эту страницу масса
Правильно, это ее документированное поведение. Потому что зачем она нужна, если не собираетесь ничего записывать? А если собираетесь - то почему не готовы? ;) |
| Автор: source777 6.3.2008, 16:49 | ||
Смысл очень большой, и состоит он в том, чтобы показывалась нормальная страница, если пользователь случайно или специально введёт что-то типа кавычки, вместо какого-нить невменяемого сообщения типа страница не найдена... Никто не отменяет фильтрацию при обращении к БД, но это оффтопик в данном случае...
ничего, не помешает. |
| Автор: Feldmarschall 6.3.2008, 17:00 |
| source777, ты очень невнимательно читаешь реплики собеседников. Во-первых, solenko задал вопрос про фильтрацию не тебе, а Хрипа. или ты хочешь сказать, что согласен с его методом? Во-вторых, не теряй нить разговора с SelenIT. Речь шла о том, что пробела никакого в урле быть, разумеется, не может. И википедия, разумеется, никакие пробелы в урле не понимает. Это должно быть понятно любому человеку, который хоть непного представляет себе работу протокола НТТР, в котором пробел является служебным символом. Тем более, что SelenIT подробно все объяснил. |
| Автор: source777 7.3.2008, 00:58 | ||||
|
| Автор: SelenIT 7.3.2008, 01:04 | ||
| source777, мы с Feldmarschallом прицепились исключительно к фразе Тут уж урлдекодом не отбиться, придется отвечать за сказанное
тоже явно не подразумевала URL-декодирование (по определению URI), так что нефиг отмазываться |
| Автор: source777 7.3.2008, 01:22 | ||
|
| Автор: SelenIT 7.3.2008, 01:28 |
| source777, то, что эта фраза относилась к коду kat_ru, было абсолютно неочевидно - для большинства людей фраза, начинающаяся с "а лучше сразу <сделать по-другому>" звучит как предложение полной альтернативы, а не маленького усовершенствования Но во фразе про Википедию даже этими "очевидными умолчательствами" не прикрыться, там просто явный ляп |
| Автор: source777 7.3.2008, 01:29 | ||
Да уж вы с Feldmarschallом, напоминает название одного фильма \"...ой и ещё ...ее\", с точки зрения пользователя, он вводит пробел, и его не колышит, что он сначала заменяется на %20, а потом на _. К тому же %20 - это в данном случае есть ничто иное как обозначение пробела и его вполне корректно пробелом и называть... Яснышко? |
| Автор: Feldmarschall 7.3.2008, 01:33 |
| source777, давай определимся. Если этот рег просматривает строку после декодирования, то в нем не хватает как минимум поддержки русских букв. И многих других символов, вполне передающихся через квери стринг. |
| Автор: SelenIT 7.3.2008, 01:35 | ||
Вот я, как пользователь, которого не колышет, и попросил показать пример - в телнете
Логично... Если на сарае написано известно что (любимое слово Арт.Лебедева), значит, сарай - это оно самое и есть Программирование - это область точной науки. Играть со словами и убеждать самого себя "да я ж совсем другое имел в виду" тут бессмысленно - программа все равно будет делать не это, а буквально то, что ты ей сказал. Яснышко? Добавлено через 1 минуту и 20 секунд ...ох, придет сейчас PARROT и надерет нам всем троим уши... |
| Автор: Feldmarschall 7.3.2008, 01:40 |
| SelenIT, давай отстанем от википедии. В конце концов, яндекс тоже корректно обрабатывает пробелы в урле. Если говорить о раскодированном варианте. Ведь нас, по большому счету, интересует не уличить друг дружку в неправоте, а сделать нормальную функцию. Чем и предлагаю совместно заняться =) Для начала я бы четко ограничил область её применения. В каких случаях нас интетесует защита от XSS? |
| Автор: SelenIT 7.3.2008, 01:49 |
| Feldmarschall, хм... мне казалось, что насчет применимости все по местам давно http://forum.vingrad.ru/index.php?showtopic=199171&view=findpost&p=1434482 solenko, а дальше пошел чистый флейм... |
| Автор: Feldmarschall 7.3.2008, 01:57 | ||
| Я не могу настаивать на своем мнении, но мне кажется, что solenko отвечал не автору. Возможно, я так думаю потому, что сам хотел ответить Хрипа то же самое. По сути же вопроса комментарий solenko не совсем в тему: переданное в квери стринг обычно не пишут в базу. Но эти рассуждения, как раз, хорошая база для определения области применения. Значит, с при помещении в базу у нас все просто: на входе мускулевский искейп, на выходе - htmlspecialchars. И никаких XSS. Теперь переходим к обработке урлов. Тут тоже, наверное, не стоит резать все чохом, а обрабатывать только там, где нужно. Насколько я себе представляю механизм, мы делаем поиск с пространичным выводом:
и подставляем это дело в ссыки на страницы. malicious user подпихивает нам вместо word конструкцию, которую мы сами, своими руками, пишем в ссылку. так? |
| Автор: SelenIT 7.3.2008, 02:11 | ||
Feldmarschall, пожалуй, ты прав. Меня сбило с толку, что следующим постом автор ответил solenko.
Так. Получается, теоретически там может быть (после URL-декодирования) что-то вроде " onclick="злобный_скрипт_в_одну_строку". Но опять же, опасно это только при выводе в HTML и точно так же обезвреживается htmlspecialchars-ом, разве нет? Опять же, если мы собираем ссылки руками, скорее всего мы их сразу же урленкодим (напр., тем же http_build_query), а что опасного может быть в заурленкоденной строке? |
| Автор: Feldmarschall 7.3.2008, 09:31 |
Ну так я ведь и пишу именно о самом, что ни на есть, выводе в HTML. О! А вот это в самую точку. Действительно - urlencode-им. А саму строку поиска, выводимую в поле формы - htmlspecialchars-им. Получается, именно эти две функции гарантируют нас от XSS? вроде бы, они предусамтривают все варианты вывода данных обратно юзеру... Или нет? |
| Автор: SelenIT 7.3.2008, 11:41 |
| Имхо, в случае корректного HTML (все атрибуты в кавычках и т.д.) - да. По крайней мере, сам пока дыр не вижу... |
| Автор: Feldmarschall 7.3.2008, 11:50 |
| Получается, развесистая функция а) не нужна вообще б) тем более не нужна на входе в) на выходе все сделает htmlspecialchars Вот теперь тема действительно соответствует статусу решённой =) Впрочем, хотелось бы подождать мнений других участников. Вообще, короткое и точное определение XSS (не принципа, а формализация учзвимости) не помешало бы. А то глупо решать задачу, не представляя точно, в чем она заключается... |
| Автор: source777 7.3.2008, 13:18 | ||||
|
| Автор: SelenIT 7.3.2008, 13:45 | ||
Засчитано |
| Автор: Feldmarschall 7.3.2008, 16:54 |
| source777, как показало наше небольшое исследование, цель ограничить допустимые символы не имеет прямого отношения к исходной задаче - защите от XSS Разве что, отдельным пунктом идет информация, помещаемая в теги <script>. Здесь надо разобраться с правилами экранирования. |
| Автор: source777 7.3.2008, 17:30 | ||
естественно это имеет мало общего с XSS в принципе, однако именно в этом и была исходная задача... |
| Автор: SelenIT 7.3.2008, 17:32 | ||
А когда такое бывает нужно? Имхо, кто вставляет юзерские данные в теги <script>, тому никакая фильтрация не поможет... |
| Автор: kat_ru 7.3.2008, 17:41 | ||||
Не совсем красивая ссылка не правда ли? Да и действительно вдруг забудешь вот - это?
в этом случае редирект с 301 статусом на адрес http ://host/1.php?page=1 будет куда лучше и полезнее... ;) а относительно - пробелов, кириллицы и т.п. дык это индивидуально ))) |
| Автор: Feldmarschall 7.3.2008, 17:45 |
| SelenIT, перейди в список тем форума, и подведи мышку к знаку вопроса в квадратных скобочках ;-) А потом согласись, что это весьма распространенная практика source777, у SQL инъекций, как и у осетрины, не бывает уровней свежести. уровень только один. данные прослешиваются обкавычиваются управляющие элементы выбираются из вариантов, заранее прописаных в скрипте, или приводятся к инту. Все. Больше никаких уровней нет. Тут наоборот - чем больше уровней, тем меньше защита. У семи нянек дитя без глазу - говорит русская пословица. Один уровень, но сделанный с пониманием проблемы, надежнее десяти, но основанных на слухах и домыслах. Именно поэтому я хочу решать исходную задачу, а не то, что написал автор. Добавлено через 14 минут и 7 секунд kat_ru, об этом и речь. Что есть универсальные решения, которые работают для любых случаев, а есть системы, состоящие из заплаток, ставящихся "индивидуально". Здесь тот же самый неверный подход, который мы видим в борьбе с SQL инъекциями. Прослешивание/обкавычивание нужно делать всегда. Не только, и не столько ради защиты, а потому что синтаксис такой. И добавлять к этому синтаксису проверки на разнообразные "вредные символы" - бессмысленно. И вредно. Получается, у нас не база данных, а дискотека с фейсконтролем. Так и в твоем случае. Урленкодить надо всегда. Не потому что защита, а потому что синтаксис такой. Соблюдаешь ты синтаксис пхп? И синтаксис хтмл надо соблюдать. |
| Автор: source777 7.3.2008, 18:41 | ||||||
Лишая защиту многоуровневости - ты лишаешь сайт многих разных вкусностей, например лога попыток SQL-инъекций, для дальнейшего забанивания IP.
Пока ты ничего универсального правда не придумал... ведь вышеописанную ситуацию твой код обработать не сможет, т.к. получит либо \'1, либо 0, но никак не нужное значение = 1. |
| Автор: kat_ru 7.3.2008, 18:52 | ||
Чту и уважаю! И соответственно соблюдаю. |
| Автор: SelenIT 7.3.2008, 20:46 | ||||||
Каюсь, ни одной не нашел. И сам ни разу не встречался...
Имхо, как раз отображать одно и то же для разных урлов - криво, и с точки зрения SEO, и чисто эстетически. Я бы для первого урла выдавал 404 и не парился. Чем это оно нужное? Очевидно же, что это ошибка, равно как и http://site/page/nepomnuvrodebylo1 - нет такого раздела, и баста...
Где связь? И чем фильтрация query_string-а может помочь логированию иньекций? Имхо, наоборот помешает - насколько я понял, при твоем подходе для описанной ситуации в лог запишется безобидная единичка... Если на то пошло, то настоящая многоуровневость - это именно то, за что ратует Feldmarschall, когда с каждой заразой борются прицельно в том месте, где она может дать о себе знать: с SQL-иньекцией (включая лог попыток таковой) - при составлении запроса, с XSS - при выводе. И лишает ее как раз попытка нагородить все заборы в одном месте, как в том анекдоте ("...надеть ср-во от гол. боли, намазать йодом, надеть поверх другое, намазать зеленкой, перебинтовать... и никаких половых контактов!"). |
| Автор: source777 7.3.2008, 21:42 |
| Это такая же ошибка, как и то, что возможно универсальное решение... В мире так мало что универсально, даже законы сохранения имеют границы применимости, поэтому любое \"универсальное\" решение имеет как минимум одну ошибку... |
| Автор: SelenIT 7.3.2008, 21:54 |
| source777, я имел в виду, что для системы, ожидающей http://site/page/1, появление на входе http://site/page/'1 - явно нештатная ситуация, и выдавать при ней тот же контент, что и для http://site/page/1 - имхо, некорректно. И вообще разные URL для одного контента - зло. В данном примере, имхо, логично (и для пользователя, и для поисковиков) выдать кастомную страницу 404 со ссылками на http://site/page/1, http://site/page/11 и т.п. ("возможно, вам нужно это?"), как это делает, например, онлайновый PHP-мануал |
| Автор: Feldmarschall 7.3.2008, 22:05 |
| SelenIT, вы незаметно перешли к обсуждению вопросов юзабилити. А эти вопросы, в отличие от технических, действително имеют много вариантов решения. Думаю, тут давно уже пора поставить точку. Каждый остался при своем мнении, и врядли его уже изменит. Хочу сказать спасибо автору и source777 за то, что они заставили меня лишний раз задуматься о проблеме XSS и придумать приемлемое универсальное решение. Жаль только, что source777 не привел конкретных примеров неудачности универсального решения, а ограничился общими фразами о том, что это плохо. Подход kat_ru... Не знаю. Наверное, имеет право на существование. Он сродни волшебным кавычкам: "а вдруг сам прослешить забудешь? Лучше мы на автомате все входящее прослешим! а что данные побьются, то это не беда. пострипаем при нужде". |
| Автор: SelenIT 7.3.2008, 22:14 | ||
Имхо, тут вопрос на стыке юзабилити и защитного программирования, а именно - что делать с мусором на входе. Безотносительно к юзабилити (которым ради безопасности, действительно, и малость пожертвовать не грех) я категорически не согласен с вариантом, при котором мусор на входе рассматривается как вариант штатного случая, да еще идет гадание, какого именно. Сорри, тут уже я потерял нить, что мы в итоге приняли за таковое? У меня сложилось мнение, что речь была о чем-то абстрактном +1
В каких ситуациях? |
| Автор: Feldmarschall 7.3.2008, 22:26 |
| Ну, жили же волшебные кавычки много лет. И до сих пор живут на многих сайтах. Но вреда-то от них не так уж много. Ну поругается немного source777, на неверно отображённый рег, но это ведь не смертельно =) Ну, я для себя решил, что htmlspecialchars+rawurlencode предохраняют меня от XSS. Буду рад услышать возражения. |
| Автор: source777 7.3.2008, 22:34 |
| так приемлимое или универсальное? ты его сформулируй в виде кода и определись, ибо слова \"универсальное\" и \"приемлимое\" явно несочетаемы... |
| Автор: SelenIT 7.3.2008, 22:43 |
С тем багом, кстати, вообще какая-то сверхъестественная загадка. Волшебные кавычки явно ни при чем - не могут же они по-разному работать для разных пользователей? Есть шанс найти еще одно исключение для FAQ-а ;) Я того же мнения, плюс аксиома "все значения атрибутов - в кавычках". Для меня это общий принцип (универсальный;), на основании которого я всегда могу сделатьрешение для каждого конкретного случая. И пока не вижу разумных случаев, где этого не было бы достаточно. |