Cross-Site Scripting [XSS]
Last updated
Last updated
На этой странице мы рассмотрим основные принципы защиты от XSS, независимо от вектора атаки. Однако мы не будем рассматривать негативные последствия, которые могут вызвать XSS-атаки; для получения более подробной информации о дальнейшей эксплуатации этой атаки, пожалуйста, .
Даже если ваш сервер защищен, лучшей мишенью для хакеров является веб-браузер. Откровенно говоря, браузеры выполняют любой JavaScript-код, который появляется на любой веб-странице. Поскольку межсайтовые скриптовые атаки действительно распространены, мы можем разделить их на три типа:
Stored XSS.
Reflected XSS.
DOM-Based XSS.
Хранимые атаки - это атаки, в которых внедренный скрипт постоянно хранится на целевых серверах, например в базе данных, в форуме сообщений, журнале посетителей, поле для комментариев и т. д. Затем жертва получает вредоносный скрипт с сервера, когда запрашивает сохраненную информацию. Хранимый XSS также иногда называют Persistent или Type-I XSS.
Первый шаг к предотвращению межсайтового скриптинга в идеале означает экранирование всего динамического содержимого, поступающего из базы данных, таким образом, чтобы браузер интерпретировал содержимое HTML-тегов, а не весь контент как необработанный HTML.
&
&
'
'
<
<
>
>
Вот пример того, как может выглядеть экранирование и отображение полученной из базы данных информации:
Это преобразование экранированных символов происходит, конечно, после того, как браузер построил DOM для страницы, чтобы не выполнять тег. Поскольку межсайтовый скриптинг является такой распространенной уязвимостью, современные фронтенд-фреймворки, скорее всего, уже экранируют динамический контент по умолчанию. Обычно строковые переменные в представлениях экранируются автоматически.
Вот пример того, как ReactJS справляется с экранированием ответа:
Хотя фронтенд-фреймворки, как правило, уже умеют работать с динамическим контентом, это ограничивается только его отображением. Если есть возможность использовать этот контент внутри <a href={...} />, <img src={...} />
разработчик должен предпринять другие защитные меры, чтобы убедиться, что получаемые данные правильно экранированы.
Мы посвятим целую страницу всему, что связано с CSP, однако стоит упомянуть некоторые общие аспекты того, как CSP защищают от межсайтового скриптинга.
Современные браузеры позволяют веб-сайтам устанавливать политику безопасности контента, которую вы можете использовать для блокировки выполнения JavaScript на вашем сайте.
Это очень простая политика, которая ограничивает импортируемые сценарии страницы одним и тем же доменом (я) и указывает браузеру, что встроенный JavaScript НЕ должен выполняться.
Вы также можете задать политику безопасности содержимого вашего сайта в теге <head>
в HTML веб-страниц.
Отраженные атаки - это атаки, в которых внедренный скрипт отражается от веб-сервера, например, в сообщении об ошибке, результатах поиска или любом другом ответе, включающем часть или весь введенный пользователем текст запроса.
Когда жертва обманом переходит по вредоносной ссылке, отправляет специально созданную форму или даже просто просматривает вредоносный сайт, внедренный код "путешествует" на уязвимый веб-сайт, который отражает атаку обратно в браузер пользователя. После этого браузер выполняет код, поскольку он пришел с "доверенного" сервера. Отраженный XSS также иногда называют непостоянным или XSS второго типа.
Частыми мишенями для отраженного XSS являются страницы поиска и страницы ошибок, поскольку они отображают часть строки запроса обратно пользователю.
XSS-уязвимости на основе DOM обычно возникают, когда JavaScript получает данные из контролируемого злоумышленником источника, например URL, и передает их в поглотитель, поддерживающий динамическое выполнение кода, например eval() или innerHTML. Это позволяет злоумышленникам выполнить вредоносный JavaScript, который, как правило, позволяет им захватить учетные записи других пользователей.
Reflected и Stored XSS - это инъекции на стороне сервера, в то время как DOM-based XSS - это инъекции на стороне клиента (браузера). В случае Reflected/Stored атака внедряется в приложение во время обработки запросов на стороне сервера, когда недоверенный ввод динамически добавляется в HTML. Для DOM XSS атака внедряется в приложение во время выполнения непосредственно на клиенте.
Вот пример того, как может выглядеть уязвимая страница с использованием HTML5 и JavaScript:
Как вы можете судить по этой строчке:
Мы добавляем значение имени текущего элемента в DOM без какой-либо проверки ввода, и это уязвимо для DOM XSS-инъекции, так что если злоумышленник введет вредоносную инъекцию, листинг нашего элемента выполнит ее.
Мы последуем примеру защитных техник Stored XSS и Reflected XSS в том смысле, что первым делом нам нужно избавиться от всех вводимых пользователем данных. Поскольку наш код - это обычный JavaScript, мы должны создать новую функцию, которая будет делать это за нас:
Теперь нам нужно исключить то, что будет отображаться, а это наш запрос, введенный пользователем. В качестве дополнительного уровня безопасности мы можем использовать textContext вместо innerHTML, поскольку мы не хотим изменять сам HTML-узел. Кроме того, textContext также экранирует символы HTML-разметки, поэтому мы получаем их в виде escaped, что предотвращает выполнение вредоносного HTML.