如何使实时 HTML 预览文本区域安全地防止 HTML/Script 注入
How to make a live HTML preview textarea safe against HTML/Script Injection
我转向这里是不得已的办法。我已经搜索过 google,但我在寻找解决方案时遇到了麻烦。我有一个带有 textarea 元素的表单,允许您在该区域中键入 html,如果您启用了预览模式,它将在您键入时实时呈现 HTML 标记。与 Whosebug 在新 post.
下方显示预览的方式没有太大区别
但是,我最近发现我的功能存在漏洞。我所要做的就是输入如下内容:
</textarea>
<script>alert("Hello World!");</script>
<textarea style="display: none;">
并且不仅 运行 在文本区域内有效,如果您保存表单并在不同页面上重新加载所述数据,此代码仍会在所述不同页面的文本区域内执行,但用户不知道;对他们来说,所有人都看到了一个文本区域(如果没有明显的警报)。
我找到了这个 post; Live preview of textarea input with javascript html,并尝试将我的 JS 重构为那里接受的答案,因为我注意到我无法在 JSFiddle 示例中编写脚本标记,尽管也许是某些 JSFiddle 阻止了该行为,但我无法得到它在我的 JS 文件中工作。
这几行是我用来实时渲染的 HTML 标记:
$(".main").on("keyup", "#actualTextArea", function () {
$('#previewTextArea').html($('#actualTextArea').val());
});
$(".main").on("keydown", "#actualTextArea", function () {
$('#previewTextArea').html($('#actualTextArea').val());
});
有没有一种方法可以重构它以使其安全?我目前唯一的想法是擦除实时预览并使用切换 on/off 并对其进行编码,但我真的认为这是一个很酷的功能并且希望保持实时而不是切换。有没有办法 "live encode" 它或转义某些标签或其他东西?
为了清理您的文本区域预览,只需将所有 <
和 >
替换为它们的 html 字符代码等效项:
function showPreview()
{
var value = $('#writer').val().trim();
value = value.replace("<", "<");
value = value.replace(">", ">");
$('#preview').html(value);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea id="writer" onInput="showPreview();">
</textarea>
<br/>
<hr/>
<div id="preview">
</div>
编辑:实际上,我认为这个解决方案更简洁一些,并且不需要下面的代码。在速度页面中,所需要做的就是利用 Spring 框架。所以我用这样的方式替换文本区域:
#springBindEscaped("myJavaObj.textAreaText" true)
<textarea id="actualTextArea" name="${status.expression}" class="myClass" rows="10" cols="120">$!status.value</textarea>
这与一些后端 Java 验证相结合,最终成为一个更简洁的解决方案。
但是如果你想要一个非spring/速度的解决方案,那么下面这个就可以了
我拼凑了一个快速修复程序,因为我的主要目的是消除其他人轻松执行脚本的能力。这并不理想,我"m not claiming it to be the best answer, so if someone finds a better solution, please do share. I created a "sanitize" 函数是这样的:
function sanitize(text){
var sanitized = text.replace("<script>", "");
sanitized = sanitized.replace("</script>", "");
return sanitized;
}
那么前两个事件处理程序现在看起来像:
$(".main").on("keyup", "#actualTextArea", function () {
var textAreaMarkup = $('#actualTextArea').val();
var sanitizedMarkup = sanitize(textAreaMarkup );
$('#actualTextArea').val(sanitizedMarkup);
$('#previewTextArea').html(sanitizedMarkup);
});
// This one can remain unchanged and infact needs to be
// If it's the same as above it will wipe the text area
// on a highlight-backspace
$(".main").on("keydown", "#actualTextArea", function () {
$('#previewTextArea').html($('#actualTextArea').val());
});
连同 Java 防止任何有害内容存储在数据库中的边际卫生,这符合我的目的,但如果存在更好的解决方案,我非常愿意接受。
我转向这里是不得已的办法。我已经搜索过 google,但我在寻找解决方案时遇到了麻烦。我有一个带有 textarea 元素的表单,允许您在该区域中键入 html,如果您启用了预览模式,它将在您键入时实时呈现 HTML 标记。与 Whosebug 在新 post.
下方显示预览的方式没有太大区别但是,我最近发现我的功能存在漏洞。我所要做的就是输入如下内容:
</textarea>
<script>alert("Hello World!");</script>
<textarea style="display: none;">
并且不仅 运行 在文本区域内有效,如果您保存表单并在不同页面上重新加载所述数据,此代码仍会在所述不同页面的文本区域内执行,但用户不知道;对他们来说,所有人都看到了一个文本区域(如果没有明显的警报)。
我找到了这个 post; Live preview of textarea input with javascript html,并尝试将我的 JS 重构为那里接受的答案,因为我注意到我无法在 JSFiddle 示例中编写脚本标记,尽管也许是某些 JSFiddle 阻止了该行为,但我无法得到它在我的 JS 文件中工作。
这几行是我用来实时渲染的 HTML 标记:
$(".main").on("keyup", "#actualTextArea", function () {
$('#previewTextArea').html($('#actualTextArea').val());
});
$(".main").on("keydown", "#actualTextArea", function () {
$('#previewTextArea').html($('#actualTextArea').val());
});
有没有一种方法可以重构它以使其安全?我目前唯一的想法是擦除实时预览并使用切换 on/off 并对其进行编码,但我真的认为这是一个很酷的功能并且希望保持实时而不是切换。有没有办法 "live encode" 它或转义某些标签或其他东西?
为了清理您的文本区域预览,只需将所有 <
和 >
替换为它们的 html 字符代码等效项:
function showPreview()
{
var value = $('#writer').val().trim();
value = value.replace("<", "<");
value = value.replace(">", ">");
$('#preview').html(value);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea id="writer" onInput="showPreview();">
</textarea>
<br/>
<hr/>
<div id="preview">
</div>
编辑:实际上,我认为这个解决方案更简洁一些,并且不需要下面的代码。在速度页面中,所需要做的就是利用 Spring 框架。所以我用这样的方式替换文本区域:
#springBindEscaped("myJavaObj.textAreaText" true)
<textarea id="actualTextArea" name="${status.expression}" class="myClass" rows="10" cols="120">$!status.value</textarea>
这与一些后端 Java 验证相结合,最终成为一个更简洁的解决方案。
但是如果你想要一个非spring/速度的解决方案,那么下面这个就可以了
我拼凑了一个快速修复程序,因为我的主要目的是消除其他人轻松执行脚本的能力。这并不理想,我"m not claiming it to be the best answer, so if someone finds a better solution, please do share. I created a "sanitize" 函数是这样的:
function sanitize(text){
var sanitized = text.replace("<script>", "");
sanitized = sanitized.replace("</script>", "");
return sanitized;
}
那么前两个事件处理程序现在看起来像:
$(".main").on("keyup", "#actualTextArea", function () {
var textAreaMarkup = $('#actualTextArea').val();
var sanitizedMarkup = sanitize(textAreaMarkup );
$('#actualTextArea').val(sanitizedMarkup);
$('#previewTextArea').html(sanitizedMarkup);
});
// This one can remain unchanged and infact needs to be
// If it's the same as above it will wipe the text area
// on a highlight-backspace
$(".main").on("keydown", "#actualTextArea", function () {
$('#previewTextArea').html($('#actualTextArea').val());
});
连同 Java 防止任何有害内容存储在数据库中的边际卫生,这符合我的目的,但如果存在更好的解决方案,我非常愿意接受。