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

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

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

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

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

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

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

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

有帮助吗?

解决方案

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

白名单原始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将单击处理程序绑定到 .sanitized div 之间切换<代码> .raw 和 .notice

CSS:

.raw {
  display: none;
}

jQuery的:

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

其他提示

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

最安全的方法是:

  1. HTML编码所有文本。

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

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

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top