.Text() безопасно или нет для очистки данных? [JQuery]

Я видел, что этот вопрос был задан в другом месте:

Экранирование строк HTML с помощью jQuery

Ответ, помеченный @travis как правильный, говорит, что.text() в порядке. Однако некоторые люди упоминают в комментариях (например, @nivcaner и @lior), что это решение не является хорошим. Где мы находимся? Могу ли я безопасно использовать его?

Я работаю над веб-приложением, где пользователь может создать документ в своем браузере, где таблицы, заголовки и видео могут быть добавлены через JQuery. Когда пользователь "сохраняет" свой документ, его структура переводится в массив, где все элементы массива состоят из "чистого" текста без тегов (например, для каждой ячейки таблицы имеется один элемент массива, который содержит текст этого сотовый и т. д.). Затем массив преобразуется в формат JSON, отправляется на сервер и обрабатывается / обрабатывается / сохраняется в формате JSON через PHP.

После этого к документу могут получить доступ другие пользователи, и это, конечно, создает потенциальные дыры в безопасности. Идея состоит в том, что они читают данные JSON с сервера, а затем воссоздают документ через javascript/JQuery на стороне клиента.

Хотя я довольно уверен, что мой PHP-код выполняет свою работу по надлежащей очистке данных JSON, я боюсь некоторой атаки, когда злонамеренный пользователь может заставить других пользователей читать данные JSON из ненадежного источника. По этой причине у меня есть ощущение, что лучше также проверить любые данные JSON, поступающие с сервера, перед повторным созданием таблиц и т. Д. На стороне клиента. Предполагая, что переменная currentCellText содержит текст (чтение JSON), который будет записан в ячейке таблицы #mytdМогу ли я безопасно использовать код $("#mytd").text(currentCellText) воссоздать содержимое ячейки?

1 ответ

Решение

Из статьи jQuery .text():

Мы должны знать, что этот метод экранирует предоставленную строку по мере необходимости, чтобы он правильно отображался в HTML. Для этого он вызывает метод DOM.createTextNode(), не интерпретирует строку как HTML.

Это означает, что данные сохраняются в текстовом узле, который по спецификации не может отобразить сохраненный текст как HTML, поэтому $("#mytd").text(currentCellText) должен быть в безопасности.

Строка 1.x реализации jQuery поддерживает эту статью. Когда вы посмотрите на несжатый источник для jQuery 1.11.3, вы обнаружите это:

jQuery.fn.extend({
    text: function( value ) {
        return access( this, function( value ) {
            return value === undefined ?
                jQuery.text( this ) :
                this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) );
        }, null, value, arguments.length );
    },
    ...

Соответствующая строка такова:

this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) );

Большая часть строки просто найти правильный document с помощью которого создать текстовый узел, но value который передается в строке, никогда не будет интерпретироваться как HTML.

Кроме того, просматривая несжатый код для jQuery 2.1.4, вы обнаружите, что реализация использует .textContent атрибут для назначения, который основывается на реализации браузера для полной очистки переданного текста, а не частичной:

jQuery.fn.extend({
    text: function( value ) {
        return access( this, function( value ) {
            return value === undefined ?
                jQuery.text( this ) :
                this.empty().each(function() {
                    if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
                        this.textContent = value;
                    }
                });
        }, null, value, arguments.length );
    },
    ...

Соответствующая часть этого кода находится здесь:

this.empty().each(function() {
    if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
        this.textContent = value;
    }
});

Поскольку это то, что выполняется, когда аргумент передается .text() функция.

Другие вопросы по тегам