Сравнение безопасности eval и innerHTML для клиентского javascript?

Я экспериментировал с innerHTML, чтобы попытаться выяснить, где мне нужно усилить безопасность на webapp, над которым я работаю, и я наткнулся на интересный метод инъекций на mozilla docs, о котором я не думал.

var name = "<img src=x onerror=alert(1)>";
element.innerHTML = name; // Instantly runs code.

Это заставило меня задуматься.) Если я вообще буду использовать innerHTML и b.), если это не проблема, почему я избегаю других методов вставки кода, в частности eval.

Предположим, что я запускаю javascript clientside в браузере, и я принимаю необходимые меры предосторожности, чтобы не подвергать любую конфиденциальную информацию легкодоступным функциям, и я попал в какой-то произвольно определенный пункт, где я решил innerHTML не является угрозой безопасности, и я оптимизировал свой код до такой степени, что меня не обязательно беспокоит очень незначительный удар производительности...

Я создаю какие-либо дополнительные проблемы, используя eval? Существуют ли другие проблемы безопасности, кроме чистой инъекции кода?

Или, наоборот, есть innerHTML то, с чем я должен проявлять ту же самую осторожность? Это так же опасно?

Ответы

Ответ 1

TL;DR;

Да, вы правы в своем предположении.

Настройка innerHTML подвержена атакам XSS, если вы добавляете ненадежный код.

(Если вы добавляете свой код, хотя это меньше проблемы)

Рассмотрите возможность использования textContent, если вы хотите добавить текст, который добавили пользователи, он избежит его.

В чем проблема

innerHTML устанавливает HTML-содержимое DOM node. Когда вы устанавливаете содержимое DOM node на произвольную строку, вы уязвимы для XSS, если вы принимаете ввод пользователя.

Например, если вы установите innerHTML для node на основе ввода пользователя из параметра GET. "Пользователь A" может отправить "Пользователь B" версию вашей страницы с помощью HTML, в котором говорится: "Украдите пользовательские данные и отправьте их мне через AJAX".

Подробнее см. этот вопрос здесь.

Что можно сделать, чтобы уменьшить его?

Что вы можете захотеть, если вы устанавливаете HTML-узлы:

  • Использование механизма моделирования шаблонов, например Mustache, который обладает возможностями экранирования. (По умолчанию он удалит HTML)
  • Использование textContent для установки текста узлов вручную
  • Не принимать произвольные данные от пользователей в текстовые поля, самостоятельно дезактивируя данные.

Смотрите этот вопрос на более общие подходы к предотвращению XSS.

Ввод кода - проблема. Вы не хотите быть на приемной стороне.

Слон в комнате

Это не единственная проблема с innerHTML и eval. Когда вы меняете innerHTML DOM node, вы уничтожаете его узлы контента и вместо этого создаете новые. Когда вы вызываете eval, вы вызываете компилятор.

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

Ответ 2

Быстрый ответ: вы не думали ничего нового. Во всяком случае, хотите ли вы еще лучшего?

<scr\0ipt>alert("XSSed");</scr\0ipt>

В нижней строке указано, что существует больше способов запуска XSS, чем вы думаете. Все следующие действия:

  • onerror, onload, onclick, onhover, onblur и т.д.... являются действительными
  • Использование кодировки символов для обхода фильтров (нулевой байт выделен выше)

eval попадает в другую категорию, однако - это побочный продукт, большую часть времени которого запутывают. Если вы падаете на eval, а не innerHTML, вы находитесь в очень маленьком меньшинстве.

Ключом к этому является дезинфекция ваших данных с помощью анализатора, который постоянно обновляется с помощью тех, которые просматривают тестеры пера. Есть пара таких людей. Они абсолютно нуждаются, чтобы по крайней мере отфильтровать все те из OWASP список - те, которые довольно часто.

Ответ 3

innerHTML само по себе не является безопасным. (Не eval, если используется только в вашем коде. Это на самом деле более плохая идея по нескольким причинам.) Отсутствие безопасности возникает при отображении контента, представленного посетителем. И этот риск применяется к любому механизму, с помощью которого вы вставляете пользовательский контент: eval, innerHTML и т.д. На стороне клиента и print, echo и т.д. На стороне сервера.

Все, что вы помещаете на странице посетителя, должно быть дезинфицировано. Не важно, выполняете ли вы это, когда начальная страница создается или добавляется асинхронно на стороне клиента.

Итак... да, вам нужно проявлять некоторую осторожность при использовании innerHTML, если вы показываете содержимое, представленное пользователем.