Прием потенциально опасных символов и предотвращение сохраненных XSS

#security #xss

#Безопасность #xss

Вопрос:

У меня есть несколько полей в веб-приложении, требование которых состоит в том, чтобы принимать любые символы и сохранять их в базе данных. Позже они извлекаются и отображаются несколькими способами, включая привязку jQuery, фреймворк MVVM и т. Д.

Каков правильный способ приема и обработки этих данных? Должен ли я кодировать данные на стороне сервера перед их сохранением или сохранять их в исходном формате? Должен ли я анализировать каждый метод рендеринга, чтобы увидеть, как они безопасно обрабатывают данные?

Ответ №1:

TL; DR: Это последнее, XSS — проблема кодирования вывода.

Вы можете хранить любой пользовательский ввод в своей базе данных, что само по себе не является уязвимым. Конечно, если вы можете, вам следует выполнить проверку входных данных, но иногда из-за характера данных, которые вы ожидаете получить при нормальной работе, вы не можете проверить некоторые входные данные. Это не огромная проблема, XSS в целом в любом случае не может быть остановлен проверкой ввода.

Одним из аргументов против хранения закодированных значений в базе данных является то, что это разделение проблем. Существует несколько разных кодировок (HTML, Javascript, URL, XML и т. Д.), И компонент, который получает данные, может (и должен) не иметь ничего общего с тем, который позже их отображает. Другой аргумент против этого связан с тем, что при сохранении данных вы не хотите знать, как они будут отображаться, поэтому вы не можете выбрать правильную кодировку. Также поиск или упорядочение будут намного сложнее с закодированными данными. Поэтому вы должны просто сохранить его как полученный.

Чтобы предотвратить XSS, вы должны тщательно реализовать кодировку вывода в соответствии с контекстом (обычный html, javascript, json, xml, что угодно) при записи таких данных в какой-либо вывод. Обратите внимание, что это совсем не просто, например, на HTML-странице контекст javascript создается не только блоком сценария, но и, например, атрибутами события (onclick , onmouseover и т. Д.), Как и href для тега < a >, Если переменная является первым символомзначение href (см. javascript:alert(1) ).

Но суть в том, что вам всегда нужно находить правильный метод кодирования и кодировать все ваши переменные при записи их в выходные данные.

MVVM — это несколько особый случай. Большинство шаблонов на стороне клиента имеют методы для записи переменной в кодированном или необработанном виде, также привязка данных на стороне клиента обычно предоставляет средства для привязки переменной в виде анализируемого html-узла или просто в виде текста. Очевидно, что вы должны выбрать текст, html может быть уязвим для XSS, если задействован пользовательский ввод. Это практически означает такие вещи, как использование text: привязки в Knockout вместо html: или использование .text() метода jQuery вместо .html() .

В этих случаях данные обычно загружаются в AJAX-запросе в виде JSON, где их по-прежнему не нужно кодировать, потому что вы все еще не обязательно знаете, где вы будете их использовать, и вы все равно можете захотеть выполнить поиск / сортировку на клиенте (но чтобы это не было уязвимым, вы нужно отправить его с application/json типом контента, а не text/html ). Но это всего лишь данные, а JSON — это просто формат данных. Конечно, его нужно закодировать в JSON, но стандартные сериализаторы объектов делают это за вас. Если вы хотите сгенерировать JSON на странице (скажем, для инициализации SPA), вам нужно кодировать значения в HTML в объекте JSON — лучше и проще получить эти данные с помощью AJAX.