C# 如何在ASP.NET MVC 5中进行白名单HTML编码?

C# 如何在ASP.NET MVC 5中进行白名单HTML编码?,c#,asp.net,asp.net-mvc,markdown,xss,C#,Asp.net,Asp.net Mvc,Markdown,Xss,我正在为我的一个项目开发一个迷你CMS模块,在这个模块中,用户可以编辑降价的内容。我正在使用标记它进行解析并显示预览 我一直在思考如何将输入发送到服务器,以及如何将其存储在数据库中。我得出了一个结论,以避免重复服务器端的标记解析,并将标记和解析的HTML都发送到服务器。我认为现在增加的开销是最小的,即使在编辑量很大的网站上也是如此 所以在最后阶段,我仍然需要验证发送到服务器的HTML,因为它可能是系统的安全瓶颈。我已经读了很多关于微软的AntiXSS的实现,以及它是如何(或曾经)在这种情况下不可

我正在为我的一个项目开发一个迷你CMS模块,在这个模块中,用户可以编辑降价的内容。我正在使用
标记它
进行解析并显示预览

我一直在思考如何将输入发送到服务器,以及如何将其存储在数据库中。我得出了一个结论,以避免重复服务器端的标记解析,并将标记和解析的HTML都发送到服务器。我认为现在增加的开销是最小的,即使在编辑量很大的网站上也是如此

所以在最后阶段,我仍然需要验证发送到服务器的HTML,因为它可能是系统的安全瓶颈。我已经读了很多关于微软的AntiXSS的实现,以及它是如何(或曾经)在这种情况下不可用的,因为它太棒了。例如,我发现甚至有一个助手代码(使用HTMLAgilityPack)提供了一个可用的清理实现

不幸的是,在这个话题上,我没有发现比2013年更新的东西。我想问一下,目前在允许标记和属性的情况下,如何进行正确的HTML编码,但仍然可以避免任何类型的XSS攻击?是否仍然需要像本文中那样的代码,或者是否有内置的解决方案


此外,如果我选择的客户端标记解析不可行,那么还有哪些其他选项?我想避免的是,在客户端和服务器上重复各种降价逻辑。例如,我为
标记它等准备了几个自定义扩展。

如果允许在客户机上编辑html并将其存储到服务器,那么基本上就是打开了一罐蠕虫。这适用于客户端html编辑器,也适用于您希望保存从标记生成的html的用例。问题是恶意用户可能会将任何html发送到您的后端,而不仅仅是从标记中实际生成的html。在这种情况下,Html代码将是纯用户输入,因此不能被信任

假设您想要实现标记和标记属性的白名单,即HTMLAgilityPack方式。考虑HTML中的简单链接。显然,您希望允许
(只有Javascript库,而不是全部)从任何html内容中删除Javascript。这样做的方式是在显示任何此类html之前(在客户端预览html之前,或者在显示从服务器下载的html之前),您可以通过Caja运行它,这将删除任何Javascript,从而消除XSS。根据我的经验,它工作得相当好,它也从CSS中删除了Javascript,也删除了诸如href、src、脚本标记、事件属性(onclick、onmouseover等)之类的琐碎内容。另一个类似的库是,但它只适用于新浏览器,并且不会从CSS中删除Javascript(因为这在新浏览器中无论如何都不起作用)

  • 服务器端清理:您也可以在服务器端正确使用Caja,但对于您的用例来说,这可能太难维护了,而且如果只实现了这一点,客户端预览(没有服务器往返)仍然容易受到DOM XSS的攻击

  • 内容安全策略:您可以使用
    内容安全策略
    响应头禁用网站上的所有内联Javascript。一个缺点是,它会影响客户端架构(显然,您根本无法使用内联Javascript),而且浏览器支持有限,在不受支持的浏览器中,您的页面实际上会容易受到XSS的攻击。但是,当前主流浏览器的最新版本都支持内容安全策略,因此它确实是一个不错的选择

  • 独立框架:您可以从不同的来源(即不同的子域)提供不安全的html,并接受该来源上的XSS风险。然而,跨帧通信仍然是一个问题,身份验证和/或CSRF也是一个问题,这取决于解决方案。这是一种老式的方式,上面的选项可能更适合您的用例


  • 你也可以结合使用这些工具进行深度防御。

    我最终使用了本文中的代码。我做了一个重要的改变,我从白名单中完全删除了
    style
    属性。我不需要它们,我允许的样式可以通过类来实现。此外,
    style
    属性也很危险,很难正确编码/转义。现在我觉得代码对于我当前的目的来说足够安全。

    在MVC中,默认情况下XSS攻击是有效的。所以,如果有人试图发布javascript或HTML代码,他就会出错。@Div:这种验证基本上是无用的。您必须始终转义所有输出。@Div但它不是剥离了所有HTML吗?另一方面,当我在接收输入的相应操作上使用
    [ValidateInput(false)]
    时,它将不起任何作用。@SLaks理想情况下,我希望数据库中有已验证的HTML,因此我可以将其与其他一些数据一起以JSON的形式输出。这里有一些代码,但请注意,它仍然是黑名单这是不安全的。一般来说,你想用HTMGReliPyPACK解析HTML,然后用你认为安全的方法构造一个新文档。然后,将HTMLGraciPyPACK格式化为HTML文档。“JavaScript:alert(“”)”
    将导致未初始化的JavaScript链接。不管此漏洞如何,经过清理的href URL的代码设计都很笨拙。这就是黑名单失败的原因:他试图检测坏东西并将其删除。相反,他应该检查是否存在,例如,
    ^http://”
    值,不允许任何其他内容。也不确定他在
    评估
    检查中做了什么。似乎什么都不做,但如果它做了什么,它可能也很脆弱。重新