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

时间:2011-08-11 10:38:38

标签: c# javascript asp.net html xss

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

然后将该用户输入的内容输出到系统的其他用户。

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

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

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

是否有一种简单的方法来编写所有JavaScript代码的脚本,同时保持HTML的其余部分不受影响?

对于我的特定实现,我正在使用C#

5 个答案:

答案 0 :(得分:7)

Microsoft已经制作了自己的反XSS库 Microsoft Anti-Cross Site Scripting Library V4.0

  

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

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

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

答案 1 :(得分:4)

彼得,我想向你们介绍两个安全概念;

黑名单 - 禁止你知道的事情很糟糕。

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

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

你问的是,实际上是黑名单。如果必须替代<script>(例如<img src="bad" onerror="hack()"/>),您将无法避免此问题。

另一方面,

白名单允许您指定允许的确切条件。

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

  • 仅允许这些标签:b,i,u,img
  • 仅允许这些属性:src,href,style

这只是理论。实际上,您必须相应地解析HTML,因此需要适当的HTML解析器。

答案 2 :(得分:2)

如果你想允许一些HTML而不是全部,你应该使用像OWASP AntiSamy这样的东西,它允许你建立一个列入你所允许的标签和属性的白名单策略。

HTMLPurifier也可能是另一种选择。

由于新的属性和事件一直被添加到HTML5,因此它是白名单方法至关重要,因此任何黑名单都会在短时间内失败,并且知道所有“坏”属性也很困难。

编辑:哦,正则表达式在这里做起来有点困难。 HTML可以有很多不同的格式。标签可以是未关闭的,属性可以带引号或不带引号(单引号或双引号),您可以在代码中包含换行符和各种空格来命名一些问题。我会依赖一个经过良好测试的库,就像我上面提到的那样。

答案 3 :(得分:1)

正则表达式是工作的错误工具,你需要一个真正的HTML解析器或者事情会变坏。您需要解析HTML字符串,然后删除所有元素和属性,但允许的(白名单方法,黑名单本身就是不安全的)。您可以将the lists used by Mozilla作为起点。在那里,您还有一个带有URL值的属性列表 - 您需要验证这些属性是相对URL还是使用允许的协议(通常只有http: / https: / ftp:,特别是没有javascript:data:)。一旦删除了所有不允许的内容,就可以将数据序列化为HTML - 现在您可以安全地在网页上插入数据。

答案 4 :(得分:-1)

我尝试像这样替换标签元素格式:

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;
    }
}

保存到db之前的用法:

    string sResultNoXSS = Utility.PreventXSS(varName)

我测试过我输入的数据如下:

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

enter image description here

它将在浏览器上运行。添加Anti XSS后,上面的代码将是:

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

<之后有一个空格)

结果,该脚本不会在浏览器上运行。