#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.