Обязательный ответ на ваш первый пример
var comment = 'I\'m a naughty person!!' +
'<script src="http://blah.com/some_naughty_javascript.js">';
var $dom = $('<div>' + comment + '</div>');
Не делай этого. Вместо этого вы должны использовать API, который обрабатывает текст как текст и не подвергает вас инъекции. В этом примере вы должны сделать это:
var $dom = $('<div>').text(comment);
… который создает div
, , а затем устанавливает его текстовое содержимое. comment
никогда не анализируется как HTML, поэтому нет никаких шансов, что браузер когда-либо сделает с ним что-нибудь опасное.
Переходя к вопросу
Если я вас правильно понимаю, вы хотели бы проанализировать информацию из произвольного HTML, без того, чтобы браузер не подготовился к ее отображению (скажем, путем загрузки изображений).
Это сложно , потому что DOM, встроенные в веб-браузеры, созданы для работы с контентом, который в какой-то момент будет отображаться. JQuery (и любая библиотека, которая создает узлы DOM) ограничен этим.
DOM Level 2 определяет API для создания документов , которые полностью отделены от активного: document.implementation.createHTMLDocument(<em>title</em>)
. В моем тестировании ничего не загружается при создании img
для одного из следующих документов:
var doc = document.implementation.createHTMLDocument(''),
img = doc.createElement('img');
img.src = 'http://example.com/image.jpg'; // Nothing happens.
// Alternatively…
doc.body.innerHTML = '<img src="http://example.com/image.jpg">'; // Nope.
Итак, документ, созданный таким образом, кажется хорошей песочницей для анализа и изучения HTML. Вы даже можете создать оболочку jQuery вокруг узлов в другом документе ($(doc.body)
) и исследовать ее через API-интерфейсы jQuery. Найдя искомые узлы, вы можете преобразовать их обратно в HTML для вставки в активный документ или использовать методы , такие как importNode()
и adoptNode()
, чтобы перенести их непосредственно в активный документ .
К сожалению, поддержка всего этого является новой. Firefox поддерживает createHTMLDocument
в версии 4 и выше (аналогичный метод createDocument
, который работает с XML, доступен в более старых версиях ), а Internet Explorer поддерживает его в версии 9 и выше . Кроме того, насколько я могу судить, спецификация не гарантирует , что изображения и сценарии не будут предварительно загружены в эти документы.
Лучшим решением будет избежать парсера HTML браузера . Ряд JavaScript HTML
парсеры появились в последнее время. Самым простым из них является, вероятно, Pure JavaScript HTML Parser Джона Ресига . Вы можете кормить его HTML, и он вызывает обратные вызовы при попадании в новые теги, атрибуты и текст. С помощью этих обратных вызовов вы можете создать новый HTML, построить DOM-узлы или сохранить документ в любой удобной для вас форме, а также можете игнорировать атрибуты и узлы, которые вы считаете опасными.
Пример этого можно найти в Interpolique Дэна Камински , проверке концепции, целью которой было уничтожить XSS и SQL-инъекцию раз и навсегда. Проект не сработал, но если вы скачаете Interpolique, вы обнаружите функцию safeParse()
, застрявшую в нижней части htmlparser.js, которая использует белый список имен и атрибутов тегов и отбрасывает все остальное.
jsdom является полным (до DOM уровня 2, с некоторым уровнем 3) HTML DOM, написанным на JavaScript - вы можете использовать его для безопасной работы с HTML. Вы даже можете загрузить свою собственную копию jQuery. Однако он написан для CommonJS без учета совместимости с браузерами. Я не знаю, будет ли он работать в большинстве веб-браузеров без изменений. Это также большая библиотека.
Если это вообще возможно, идеальным решением является предоставление ответов AJAX в формате, отличном от HTML. Вам нужно вообще включать дополнительный небезопасный HTML? Если вы выполняете работу на сервере, возвращая только то, что вам нужно ...
{
"inputs": [
'<input …>',
'<input …>'
],
}
... ваша работа на стороне клиента становится намного проще.