#jquery #append #xss
#jquery #добавить #xss
Вопрос:
Я создаю редактор кода javascript для пользователей на моем сайте. Одной из функций, которые я создал, была пользовательская консоль. Пользователи могут писать console.войдите в их код, и записанная строка будет добавлена к div на странице, делая что-то вроде этого:
function toConsole(str) {
var myconsole = document.getElementById("console-text");
var message = document.createElement("span");
message.append(str);
myconsole.append(message);
}
str
устанавливается в любую строку, которую вводит пользователь console.log
. Может ли добавление этой строки запустить вредоносный код на моей странице? (На странице jQuery api .append() написано «да», но, похоже, я не могу заставить ее интерпретировать все, что я пишу, как html)
Если да, то как я могу предотвратить это и как я могу проверить, чтобы убедиться, что это безопасно?
Ответ №1:
Вы можете использовать text() для вставки содержимого в виде TextNode, что приведет к тому, что страница отобразит его не как разметку, а как обычный текст.
var stringContainingHtmlAndJavascript = '<div><b>This will be bold</b></div>';
$(document.body).text(stringContainingHtmlAndJavascript);
$(document.body).append(stringContainingHtmlAndJavascript);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Ответ №2:
Как сказал Таплар, есть разные способы. Вы также можете добавить HTML во временный тег и впоследствии извлечь текст. Смотрите мой третий пример для этого.
$(function() {
var stringContainingHtmlAndJavascript = '<div><b>This will be bold</b></div>';
$('.test1').append(stringContainingHtmlAndJavascript);
$('.test2').text(stringContainingHtmlAndJavascript);
$('.test3').text($('<i/>').append(stringContainingHtmlAndJavascript).text());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="test1"></div>
<div class="test2"></div>
<div class="test3"></div>
Ответ №3:
Я предложу вам .parseHTML()
использовать bemol, как указано в документации.
.parseHTML()
как следует из названия метода, анализирует строку для интерпретации HTML.
Третьему аргументу keepScripts
по умолчанию присвоено значение false … Установка значения true широко открыла бы ворота для сценариев.
Таким образом, он «обычно удаляет» теги скрипта. Если HTML или текст вообще не найден, он возвращается undefined
(как демонстрационный пример # 3). Таким образом, вам, вероятно, потребуется добавить if
условие, чтобы избежать добавления текста «undefined».
Итак… В приведенной ниже демонстрации я использовал ваш опубликованный «скрипт для добавления» как есть… Я только что добавил метод синтаксического анализа HTML.
ВАЖНО, случаи с 1 по 4 безопасны… Но # 5 — это нарушение. Если в анализируемом HTML есть встроенный атрибут on[event], он пройдет через «фильтр сценариев» и может быть выполнен.
$(".console_ok").on("click",function(){
toConsole( $(this).prev(".console_input").val() );
});
function toConsole(str) {
str = $.parseHTML(str)[0];
var myconsole = document.getElementById("console-text");
var message = document.createElement("span");
message.append(str);
myconsole.append(message);
}
input{
width: 60em;
}
#console-text{
height:8em;
width:20em;
background-color: #bbb;
border: 1px solid black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
console.log test #1:<input class="console_input" value="Just text">
<button class="console_ok">OK</button><br>
<br>
console.log test #2:<input class="console_input" value="<h1>Some HTML</h1>">
<button class="console_ok">OK</button><br>
<br>
console.log test #3:<input class="console_input" value="<script>alert('A script!!!');</script>">
<button class="console_ok">OK</button><br>
<br>
console.log test #4:<input class="console_input" value="<div style='height:20px;background-color:red;'><script>alert('A script!!!');</script>And some <b>bold</b> text...</div>">
<button class="console_ok">OK</button><br>
<br>
console.log test #5:<input class="console_input" value="<img src='invalid-path' onerror='alert(`JS EXECUTES HERE!!!`);'>">
<button class="console_ok">OK</button><br>
<br>
My console:<br>
<div id="console-text"></div>
(Пожалуйста, запустите в режиме полной страницы)
CodePen
Вы заметите [0]
после $.parseHTML(str)
… Это для получения элемента DOM из объекта jQuery, поскольку ваша функция — обычный JS. Ваша функция тоже может быть написана подобным образом (делает то же самое):
function toConsole(str) {
str = $.parseHTML(str);
var myconsole = $("#console-text");
var message = $("<span>");
message.append(str);
myconsole.append(message);
}
Ответ №4:
jquery.append() и jquery.html () не защищены от XSS-атаки, если вы не очистите данные, когда захотите отобразить их пользователю.
function encodeHTML(s) {
return s.replace(/amp;/g, 'amp;amp;').replace(/</g, 'amp;<').replace(/"/g, 'amp;quot;');}
но jquery.text() безопасен, потому что он не отображает html-код и выводит его в необработанном виде.