将可能不安全的用户输入从隐藏输入字段传输到DOM

时间:2012-02-27 05:49:09

标签: javascript jquery xss

以下是用户在站点上创建的页面的简化示例(他们通过填写表单创建它,然后他们获取页面的URL;下面是他们创建的页面的HTML)。

在示例中,我将获取隐藏输入字段的值,然后将其按原样放入DOM中。这会导致警报,模拟XSS攻击。

防止这样的事情的最佳方法是什么? #sourceinput的值以前是由查看下面页面的相同或不同用户输入的,并且未过滤用户的输入以删除标记。 (实际案例涉及jquery.tooltip.js插件及其bodyHandler回调;在鼠标悬停时,bodyHandler回调将获取隐藏的输入并将其显示给用户。)

解决这个问题的一种方法是在输入上删除标签;我控制隐藏文本字段中的内容,以便解决它。

另一种方法是在Javascript中剥离标签,但其中一些似乎不是100%有效:

Strip HTML from Text JavaScript

我是否缺少某种最佳实践,或者这两种最佳方式?

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<head>
<title></title>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script>google.load("jquery", "1.7.1");</script>
<script>
$(document).ready(function() {
  var badHTML = $('#sourceinput').val();
  $('#destinationdiv').html( badHTML );
  //$('#destinationdiv').text( badHTML );
});
</script>
</head>

<body>
<input type="hidden" id="sourceinput" value="&lt;script&gt;alert&#40;&#039;hi&#039;&#41;;&lt;/script&gt;" />
<div id="destinationdiv" style="width:10px;height:10px;background-color:red;"></div>
</body>
</html>

更新:我现在要解决的问题有三个部分:

  1. 当保存用户创建的页面时,我在其输入上运行PHP的strip_tags()。这些只是简短的文本字符串,如标题和blurbs,因此很少有用户希望他们可以输入HTML。这可能不适合其他情况。

  2. 当显示用户创建的页面时,我将其输入放在div中,而不是将用户输入的内容放入输入值属性中。

  3. 我使用.text()(不是.html())从该div中取出值。然后我通过下划线功能运行它(见下文)。

  4. 测试这一点 - 包括模拟跳过第一步 - 似乎有效。至少我希望没有我错过的东西。

3 个答案:

答案 0 :(得分:0)

如果您不想使用整个Underscore函数库,那么Underscore.js使用的转义函数就在这里:

var escape = function(string) {
    return (''+string).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#x27;').replace(/\//g,'&#x2F;');
};

一样使用
var safe_html = escape("<b>Potentially unsafe text</b>"); // "&lt;b&gt;hello&lt;&#x2F;b&gt;"
$("#destination").html(safe_html);

它写得很好并且知道可以工作,所以我建议不要自己动手。

答案 1 :(得分:0)

我会说你评论的内容(使用来自jquery的text()是更好的选择)。这将确保文本保留您想要的文本。过滤或剥离可能会产生不必要的副作用,例如在输入中删除数学表达式(“x is&lt; 5”)。

答案 2 :(得分:0)

什么都不做。

您正在尝试保护用户免受他/她的侵害。用户A无法对用户B造成伤害。对于您所关心的一切,用户A也可以在地址栏上键入javascript:alert('hi')并自己输入xss。无论你创建什么javascript转义功能,精明的用户总能绕过它。总而言之,这是一种毫无意义的追求。

现在,如果您开始保存用户在服务器端输入的内容,那么您一定要过滤掉内容。不要自己构建任何东西。根据您的服务器端语言,有几个选项。 OWASP's AntiSammy就是这样一种解决方案。

如果您确实选择在服务器端保存用户输入的html,请确保在将其保存到数据库之前通过antisammy或类似的库运行它。在出路的时候,你应该简单地转储HTML而不转义,因为你知道数据库中的任何东西都被清理了。