C# 如何在允许HTML输入的同时防止XSS(跨站点脚本)

C# 如何在允许HTML输入的同时防止XSS(跨站点脚本),c#,javascript,asp.net,html,xss,C#,Javascript,Asp.net,Html,Xss,我有一个网站,允许通过丰富的编辑器控件输入HTML。它的目的是允许用户使用HTML格式化文本 用户输入的内容然后输出给系统的其他用户 然而,这意味着有人可以在HTML中插入JavaScript,以便对系统的其他用户执行XSS攻击 从HTML字符串中过滤出JavaScript代码的最佳方法是什么 如果我对标记执行正则表达式检查,这是一个好的开始,但是恶意者仍然可以将JavaScript附加到标记的onclick属性 是否有一种简单易行的方法来编写所有JavaScript代码,同时保持HTML的其余

我有一个网站,允许通过丰富的编辑器控件输入HTML。它的目的是允许用户使用HTML格式化文本

用户输入的内容然后输出给系统的其他用户

然而,这意味着有人可以在HTML中插入JavaScript,以便对系统的其他用户执行XSS攻击

从HTML字符串中过滤出JavaScript代码的最佳方法是什么

如果我对标记执行正则表达式检查,这是一个好的开始,但是恶意者仍然可以将JavaScript附加到标记的onclick属性

是否有一种简单易行的方法来编写所有JavaScript代码,同时保持HTML的其余部分不变


对于我的具体实现,我使用的C

正则表达式对于这项工作来说是错误的工具,您需要一个真正的HTML解析器,否则事情会变得糟糕。您需要解析HTML字符串,然后删除所有元素和属性,但允许的元素和属性采用白名单方法,黑名单本质上是不安全的。你可以以此为出发点。这里还有一个获取URL值的属性列表-您需要验证这些是相对URL,或者使用允许的协议(通常只有http:/https:/ftp:),尤其是没有javascript:或数据:。一旦删除了所有不允许的内容,您就可以将数据序列化回HTML—现在您可以在网页上安全地插入一些内容。

Peter,我想向您介绍安全性的两个概念

黑名单-禁止你知道不好的事情

白名单-允许你知道是好的事情

虽然两者都有各自的用途,但黑名单在设计上是不安全的

你问的其实是黑名单。如果必须有一个替代方案,例如,您将无法避免此问题

另一方面,白名单允许您指定允许的确切条件

例如,您将拥有以下规则:

仅允许以下标签:b、i、u、img 仅允许以下属性:src、href、style
这只是理论。实际上,您必须相应地解析HTML,因此需要一个合适的HTML解析器。

Microsoft已经开发了自己的反XSS库,即Microsoft反跨站点脚本库V4.0:

Microsoft反跨站点脚本库V4.0 AntiXSS V4.0是一个编码库,旨在帮助开发人员保护其ASP.NET基于web的应用程序免受XSS攻击。它与大多数编码库的不同之处在于,它使用白名单技术(有时称为包含原则)来防止XSS攻击。这种方法的工作原理是首先定义一组有效或允许的字符,并对该字符集之外的任何内容进行编码—无效字符或潜在攻击。与其他编码方案相比,白名单方法提供了一些优势。此版本的Microsoft反跨站点脚本库中的新功能包括:-可自定义的HTML和XML编码安全列表-性能改进-支持中等信任的ASP.NET应用程序-HTML命名实体支持-无效Unicode检测-改进的HTML和XML编码代理字符支持-LDAP编码改进-应用程序/x-www-form-urlencoded编码支持

它使用白名单方法去除潜在的XSS内容

以下是一些与AntiXS相关的链接:


如果您想允许一些HTML而不是全部,那么应该使用类似于OWASP AntiSamy的东西,它允许您在允许的标记和属性上构建一个白名单策略

HTMLPurifier也可能是另一种选择

它是一种白名单方法,这一点至关重要,因为HTML5一直在添加新的属性和事件,因此任何黑名单都会在短时间内失败,而且了解所有坏属性也很困难


编辑:哦,正则表达式在这里有点难。HTML可以有很多不同的格式。标签可以不闭合,属性可以以单引号或双引号开头,也可以不加引号,可以在标签中使用换行符和各种空格来命名一些问题。我将依赖于一个经过良好测试的库,如我上面提到的库。

我尝试替换如下标记元素格式:

public class Utility
{
    public static string PreventXSS(string sInput) {
        if (sInput == null)
            return string.Empty;
        string sResult = string.Empty;
        sResult = Regex.Replace(sInput, "<", "< ");
        sResult = Regex.Replace(sResult, @"<\s*", "< ");
        return sResult;
    }
}
我有一个测试,输入数据如下:

<script>alert('hello XSS')</script>
它将在浏览器上运行。添加反XSS后,上面的代码将是:

< script>alert('hello XSS')< /script>

这取决于您使用的服务器端语言,还有一个空格?@Tim van Elsloo在我的特殊情况下,我使用的是asp.net/CPO。它的可能副本似乎是一个完整的HTML解析器是唯一的防弹解决方案。我将研究如何在src和href中使用javascript。@Dunhamzzz-这是关于标记内容的另一条规则。我谈论的是标签及其属性,而不是内容。关键是,尽管href/src很有用,但onclick却不是。这并不能保护您免受半个o的攻击
对于这里列出的内容:,许多黑客甚至不需要javascript:对,所以你否决了答案,因为你没有花时间阅读它。。。当然,它确实可以防止这些向量——这就是我建议使用HTML解析器的原因。一旦解析HTML并正确序列化它,所有无效的HTML输入问题就会自动消失。删除所有不被明确允许的元素和属性就足够安全了。处理javascript:只是最后一步。你认为HTML净化器是如何工作的?你是在建议OP roll使用他自己的HTML卫生设备,这在当今时代是自杀性的。不,我是在解释解决方案是如何工作的。如果OP阅读了这篇文章并决定使用现有的解决方案,那就太好了。但了解它的功能仍然至关重要,像魔法一样使用它可以神奇地解决您的问题,这可能会再次导致安全问题。更不用说你建议的解决方案只适用于PHP,但OP使用的是ASP.net/C.Ahh。C是在我的回答之后添加的,以防有人阅读此内容,只是为了记录在案。如果你想使用安全的HTML方法,以上所有方法都不适用于中等信任。仅供参考:以上所有方法都不再处于开发阶段,我在其他地方读到过关于AntiXSS没有很好实现的评论。
< script>alert('hello XSS')< /script>