Достаточно ли этого, чтобы предотвратить xss?

#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 вопроса:

  1. Потому что < и > экранируются как < и> amp;< , и amp;> безопасно ли отображать вывод ejs без эскиза?
  2. Достаточно ли того, что я делаю, в целом для защиты 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;> .