#xss
Вопрос:
Я работаю над веб-сайтом, на котором будет много пользовательского контента. В качестве редактора WYSIWYG я использую TinyMCE. В качестве движка шаблонов я использую ejs. Чтобы предотвратить XSS, я решил использовать пакет xss npm. Я использую эти пользовательские правила:
const strict = {
whiteList: {},
}
const withTags = {
whiteList: {
div: [],
strong: [],
em: [],
br: [],
ul: [],
li: [],
ol: [],
blockquote: [],
},
}
Допустим, пользователь использует текстовую область и отправляет этот код:
<script>alert("hi")</script>
В моей базе данных это сохраняется таким образом:
amp;<scriptamp;>alert("hi")amp;</scriptamp;>
Теперь, когда содержимое отображается с помощью ejs, некоторое содержимое отображается с экранированным выводом (<%= %>). Визуализированный экранированный вывод (html-страница) выглядит следующим образом:
amp;<scriptamp;>console.log("test")amp;</scriptamp;>
Тем не менее, некоторое содержимое отображается с помощью необработанного исходного вывода ejs (<%- %>). Html будет выглядеть следующим образом:
<script>console.log("test")</script>
У меня есть 2 вопроса:
- Потому что < и > экранируются как < и>
amp;<
, иamp;>
безопасно ли отображать вывод ejs без эскиза? - Достаточно ли того, что я делаю, в целом для защиты XSS?
Большое спасибо!
Комментарии:
1. Это чисто программный вопрос, и здесь он не по теме. На это можно лучше ответить ТАК.
2. @mentallurg спасибо, тогда я попробую спросить об этом.
Ответ №1:
Во-первых, ваши данные, вероятно, не сохранены в базе данных так, как вы представили. По всей вероятности, он хранится там без какой-либо кодировки (как и должно быть).
EJS сам по себе, при правильном использовании, заботится о выводе кодирования для вас, чтобы вы могли безопасно создавать параметризованный HTML. Но в вашем случае вы хотите отключить эту защиту для отображения необработанного HTML, так что да, вы должны быть осторожны. В вашем распоряжении есть несколько средств контроля безопасности.
1. Очистите
Я лично не пользовался библиотекой xss, похоже, у нее много загрузок, и, вероятно, это неплохой вариант. Но DOMPurify, вероятно, лучше. Он также не требует настройки и имеет встроенную поддержку доверенных типов (я дойду до этого через минуту).
Вы бы использовали его дважды. Во-первых, на стороне сервера, когда HTML отправляется пользователем, и во-вторых, на стороне клиента, когда HTML отображается EJS.
Если вы серьезно относитесь к безопасности, то вы подключите оповещения об аномалиях со стороны сервера к вашему SIEM/SOC и т. Д. Тогда вы будете знать, когда кто-то предпринял попытку XSS-атаки на ваш сайт.
2. Изолированные фреймы
Еще один элемент управления на стороне клиента, который вы можете реализовать,-это изолированные iframes. Вместо того, чтобы просто отображать HTML на странице, вы создаете IFRAME, присваиваете ему правильно настроенный атрибут песочницы, а затем устанавливаете очищенный HTML в качестве содержимого. Теперь, даже если что-то пойдет не так с очисткой, вредоносный HTML будет изолирован в своем собственном мире.
3. Политика Безопасности Контента
Самая крутая и (при правильном использовании) наиболее эффективная защита от XSS-это CSP. Это работает так, что вы вводите ограничения на свой веб-сайт, такие как «не выполнять сценарии», «не загружать изображения» и т. Д. А затем вы разрешаете сценарии, которые вы действительно хотите выполнить, и ничего больше. Теперь, если злоумышленнику удастся внедрить скрипт, ссылку, форму и т.д. на страницу, это не сработает, потому что это не было специально разрешено.
Я подробно писал здесь о CSP, вы даже найдете конкретные примеры для вашего случая (NodeJS и EJS) с примерами CodeSandbox в этой статье. И вообще о защите XSS вы можете прочитать подробнее здесь.
Надеюсь, это поможет!
Комментарии:
1. Большое спасибо! Я даже не знал о изолированных iframes и CSP . И да, он сохраняется в базе данных таким образом, потому что он поступает в БД таким образом. Пакет TinyMCE и xss заменяют < и > на < и >
amp;<
иamp;>
.