我正在为我的网站上的用户制作一个javascript代码编辑器。我构建的功能之一是自定义控制台。 用户可以在其代码中编写console.log,并将记录的字符串添加到页面上的div上,如下所示:
function toConsole(str) {
var myconsole = document.getElementById("console-text");
var message = document.createElement("span");
message.append(str);
myconsole.append(message);
}
str
设置为用户输入到console.log
中的任何字符串。附加此字符串可以在我的页面上运行恶意代码吗? (.append() jQuery api页面说“是”,但我似乎无法理解它来解释我用html编写的任何内容)
如果是这样,我如何防止这种情况发生,如何进行测试以确保其安全性?
答案 0 :(得分:0)
您可以使用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>
答案 1 :(得分:0)
正如塔普拉(Taplar)所说,有不同的方法。 您还可以将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>
答案 2 :(得分:0)
我会建议您.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)
...这是从jQuery对象中获取DOM元素,因为您的函数是纯JS。您的函数也可以这样写(做完全相同的事情):
function toConsole(str) {
str = $.parseHTML(str);
var myconsole = $("#console-text");
var message = $("<span>");
message.append(str);
myconsole.append(message);
}