支持样式标签的 .NET 的 HTML Sanitizer
Posted
技术标签:
【中文标题】支持样式标签的 .NET 的 HTML Sanitizer【英文标题】:HTML Sanitizer for .NET that supports style tags 【发布时间】:2012-08-12 09:12:09 【问题描述】:我正在寻找在 ASP.NET 项目中使用的良好 html 清理程序。需要注意的是,sanitizer 必须支持样式属性,其中可能包含 CSS 属性,这些属性也必须进行清理。到目前为止,我还没有找到一个好的产品来使用。在我硬着头皮写自己的消毒剂之前,我想我可能会先看看这里的人在用什么。
我查看并拒绝的库:
AntiXSS 库(旧版本不安全,新版本去除样式标签) AntiSamy .NET(未维护,在 .NET 版本中缺少必要的功能,具有过时的依赖项) AjaxControlToolkit 中的 HTMLAgilityPackSanitizer(转义样式标签)理想的情况是拥有一个基于白名单的清理程序,该清理程序还可以根据已知值或正则表达式列表验证属性值。
谁能指出我正确的方向?
【问题讨论】:
HTML Tidy 很旧,但我已经成功使用它。 不过,我不确定这是不是我要找的东西。这里的主要目标是确保用户输入不包含可执行脚本。 HTML Tidy 看起来不错,但似乎有一个非常不同的目的。 【参考方案1】:试试this native .NET HTML Sanitizer project。它可以根据需要理解样式属性(尽管它不会尝试保留 STYLE 标记,它只是删除它们)。
此外,它是基于白名单的,而不是黑名单(它使用 AngleSharp 而不是现在已弃用的 CsQuery)。也是on Nuget!
【讨论】:
【参考方案2】:看看CsQuery(我是它的主要作者)作为一种处理HTML的工具。
这是一个 .NET jQuery 端口,它为您提供通过在客户端上使用的相同方法(DOM 和 jQuery 的 API)对 HTML 的完全访问。这让您可以轻松推出自己的消毒剂。
Rick Strahl 最近在blog post 上讨论了如何清理 HTML。他展示了如何使用 HTML Agility Pack 使用他的规则来做到这一点,我在那里发表了一条评论,展示了如何使用 CsQuery 更轻松地实现相同的目标。基础就是这样,给定标签BlackList
的枚举:
CQ doc = CQ.Create(html);
// creates a grouped selector "iframe,form,script, ..."
string selector = String.Join(",",BlackList);
// CsQuery uses the property indexer as a default method, it's identical
// to the "Select" method and functions like $(...)
doc[selector].Remove();
如果您不想实际删除某些标签中的内容,例如也许您希望禁止格式化标签,您可以使用 jQuery 的 unwrap 代替。这将具有删除标签但保留其子标签的效果。
doc[selector].UnWrap();
完成后:
string cleanHtml = doc.Render();
Ricks 的帖子中有更多关于清理 javascript 事件属性等的内容,但基本上 CsQuery 是一个工具箱,具有熟悉且简单的 HTML 操作方式。创建一个按您想要的方式工作的消毒剂应该很容易。
如果您需要删除某些命名样式等操作,CsQuery 的 DOM 模型还包含直接访问样式的方法(例如,以比操作字符串更方便的方式)。例如,您可以从所有元素中删除“字体粗细”样式:
// use the [attribute] selector to target only elements with styles
foreach (IDomObject element in doc["[style]"])
if (element.HasStyle("font-weight"))
element.RemoveStyle("font-weight");
目前 CsQuery 的主要缺点是文档。它的 API 旨在尽可能地匹配浏览器 DOM 和 jQuery(考虑到 jQuery 和 C# 之间的语言差异),并且公共 API 有很好的注释,所以一旦你开始使用它应该很容易编写代码。
但有一些非标准方法(如“HasStyle”和“RemoveStyle”)是 CsQuery 独有的。不过,github 上的自述文件很好地涵盖了基本用法。它也在 Nuget 上,名称为 CsQuery
。
【讨论】:
酷。如果我最终推出了自己的消毒剂,那似乎是一个很好的研究工具。 我要试一试,制作我自己的白名单消毒剂。我假设我可以只使用“全部”选择器,然后迭代并解开任何不在我的白名单中的东西(或者如果它们存在,可能使用非谓词选择器?) 我想不出一个行不通的理由。我不知道这是否比使用标签选择器首先定位您想要的标签更有效还是更有效(与我给出的黑名单示例相同的技术),可能取决于对糟糕的比例,但出于这个目的,它可能只是少量的内容,无论哪种方式都无关紧要。 Unwrap 是否按照这里的意图进行?似乎展开会删除父级,而不是标签本身 好的,我认为上面的示例代码应该是:doc[selector].Contents.UnWrap();
【参考方案3】:
Tatham Oddie ASP.Net MVP - http://blog.tatham.oddie.com.au/2009/06/15/released-xhtml-markup-sanitizer/
我现在已经把这个推荐给了几个人。可能不会做你想做的一切,但 Tatham 是一个很棒的编码器,所以它应该会给你很多想法......
就在 AntiXSS 上,AFAIK 新版本在 HTMLAgilityPackSanitizer 中
【讨论】:
谢谢,但这些都不适合我的目的,因为它们都在属性中编码特殊字符。这对安全性有好处,因为您可以在样式属性中进行大量 XSS 黑客攻击,但我需要能够允许这些好东西。 :-(【参考方案4】:尝试查看开放实验室博客上发布的 HtmlSanitizer:http://roberto.open-lab.com/2010/03/04/a-html-sanitizer-for-c/。这个支持样式标签,非常适合用于 html 编辑器。
【讨论】:
谢谢。这是我见过的最接近的,但我不喜欢黑名单方法。例如,它不认为“行为”是样式属性中的禁止字符串,即使您可以通过行为在 IE 中执行脚本。可能还有其他我和作者不知道的事情你可以做。我还担心它不能正确解析 HTML。它可能仍然有效,但是如果您可以欺骗解析器(例如,将“>”字符放在属性值中,它会认为标签已关闭),那么您可以欺骗消毒剂。 因为我无法编辑我的评论,所以我重写了它:好吧,在这种情况下,除了选择一个库作为基础并根据您的需要对其进行自定义之外,我认为没有其他方法。这可能有点工作,但这是你真正得到你想要的东西的唯一方法。我们在工作中做了同样的事情(遗憾的是我不能分享那个代码)。 是的,这就是我最终所做的。我只是希望有更好的方法。【参考方案5】:查看 CodeProject 上的 Dead Simple HTML Sanitizer http://www.codeproject.com/Tips/529712/Dead-Simple-HTML-Sanitizer
【讨论】:
以上是关于支持样式标签的 .NET 的 HTML Sanitizer的主要内容,如果未能解决你的问题,请参考以下文章