公众可以查看用户生成的html内容的最佳方法是什么?

时间:2009-10-22 17:32:02

标签: html xss

在我的Web应用程序中,我允许发布用户生成的内容以供公共使用,类似于Stackoverflow。

处理此事的最佳做法是什么?

我目前处理用户生成内容的步骤是:

  1. 我使用MarkItUp来允许用户 格式化html的简便方法。

  2. 用户提交后 更改我通过HTML Sanitizer 运行它(滚动到 bottem)使用白名单 方法

  3. 如果消毒程序有 删除任何用户创建的内容我 不保存内容。然后我 用a返回修改后的内容 警告信息,“有些非法 检测到的内容标签和 删除双重检查你的工作和 再试一次。“

  4. 如果内容通过 清洁过程,我保存 原始的html内容到了 数据库中。

  5. 当我向客户端渲染时 将原始html传递出db 页面。

2 个答案:

答案 0 :(得分:2)

这是一种完全合理的方法。对于典型应用,这将是完全足够的。

白名单原始HTML中最棘手的部分是style属性和embed / object。有人可能想要将CSS样式放入不受信任的格式化文本块中,或者说嵌入的YouTube视频,这是有正当理由的。此问题最常见于Feed。您不能信任Feed条目中包含的任意文本块,但您不想删除,例如,突出显示CSS或Flash视频的语法,因为这会从根本上改变内容并可能使阅读它的人感到困惑。因为CSS可能包含IE中的行为等危险内容,所以如果您决定允许style属性保留,则可能需要解析CSS。使用embed / object您可能需要白名单主机名。

<强>附录

在最糟糕的情况下,HTML逃避视线中的一切可能会导致非常糟糕的用户体验。使用像HTML5解析器之类的东西通过白名单来浏览DOM要好得多。就如何向用户呈现已清理的输出而言,这更加灵活。你甚至可以这样做:

<div class="sanitized">
  <div class="notice">
    This was sanitized for security reasons.
  </div>
  <div class="raw"><pre>
    &lt;script&gt;alert("XSS!");&lt;/script&gt;
  </pre></div>
</div>

然后使用CSS隐藏.raw内容,并使用jQuery将点击处理程序绑定到在.sanitizeddiv之间切换的.raw .notice

CSS:

.raw {
  display: none;
}

jQuery的:

$('.sanitized').click(function() {
  $(this).find('.notice').toggle();
  $(this).find('.sanitized').toggle();
});

答案 1 :(得分:1)

白名单是一个很好的举动。任何黑名单解决方案都倾向于让它超出应有的范围,因为你无法想到一切。我已经看到了使用黑名单的一些注意事项(例如代码项目),如果他们设法捕获所有内容,通常它们仍然会导致其他问题,例如替换代码中的字符,以便在没有手动恢复它的情况下无法使用它

最安全的方法是:

  1. HTML编码所有文本。

  2. 匹配一组允许的标签和属性并对其进行解码。

  3. 使用正则表达式甚至可以要求每个开始标记都有一个结束标记,这样未封闭的标记就不会弄乱页面。

    你应该可以在十行代码中执行此操作,因此您链接的代码似乎过于复杂。