如何删除危险字符(即脚本标签)?

时间:2010-06-02 22:18:09

标签: c# .net javascript asp.net-mvc security

我想知道是否有任何类型的C#类或第三方库可以删除脚本标签等危险字符?

我知道你可以使用正则表达式,但我也知道人们可以编写脚本标签的方法很多,你可以欺骗正则表达式认为它没问题。

我也听说HTML Agility Pack很好,所以我想知道是否有为此制作的脚本删除课程?

修改

http://htmlagilitypack.codeplex.com/Thread/View.aspx?ThreadId=24346

我在他们的表格上找到了这个。但是我不确定这是否是完整的解决方案,因为这个家伙没有任何测试支持它,如果这是在一些网站,每天使用这个脚本的大量人来测试看看是否有任何东西会更好由

  

很好的例子(差不多),谢谢!一些   我看到的方法让它更强大,   虽然:

     

1)何时使用不区分大小写的搜索   寻找与“javascript:”的链接,   “vbscript:”,“jscript:”。例如,   原始示例不会删除   HTML:

<a href="JAVAscRipt:alert('hi')">click> me</a>
     

2)删除任何样式属性   包含表达式规则。互联网   Explorer评估CSS规则   表达为脚本。例如,   以下将产生一个消息框:

<div style="width:expression(alert('hi'));">bad> code</div>
     

3)同时删除标签

     

老实说,我不明白为什么   “表达”尚未被删除   IE - 我认为的主要缺陷。 (尝试   Internet Explorer中的div示例   你会明白为什么 - 甚至IE8。)我   只是希望有一个更容易/标准   从a清理html输入的方法   用户。

以下是使用这些改进更新的代码。如果你发现任何错误,请告诉我:

    public string ScrubHTML(string html)
    {
        HtmlDocument doc = new HtmlDocument();
        doc.LoadHtml(html);

        //Remove potentially harmful elements
        HtmlNodeCollection nc = doc.DocumentNode.SelectNodes("//script|//link|//iframe|//frameset|//frame|//applet|//object|//embed");
        if (nc != null)
        {
            foreach (HtmlNode node in nc)
            {
                node.ParentNode.RemoveChild(node, false);

            }
        }

        //remove hrefs to java/j/vbscript URLs
        nc = doc.DocumentNode.SelectNodes("//a[starts-with(translate(@href, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), 'javascript')]|//a[starts-with(translate(@href, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), 'jscript')]|//a[starts-with(translate(@href, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), 'vbscript')]");
        if (nc != null)
        {

            foreach (HtmlNode node in nc)
            {
                node.SetAttributeValue("href", "#");
            }
        }


        //remove img with refs to java/j/vbscript URLs
        nc = doc.DocumentNode.SelectNodes("//img[starts-with(translate(@src, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), 'javascript')]|//img[starts-with(translate(@src, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), 'jscript')]|//img[starts-with(translate(@src, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), 'vbscript')]");
        if (nc != null)
        {
            foreach (HtmlNode node in nc)
            {
                node.SetAttributeValue("src", "#");
            }
        }

        //remove on<Event> handlers from all tags
        nc = doc.DocumentNode.SelectNodes("//*[@onclick or @onmouseover or @onfocus or @onblur or @onmouseout or @ondoubleclick or @onload or @onunload]");
        if (nc != null)
        {
            foreach (HtmlNode node in nc)
            {
                node.Attributes.Remove("onFocus");
                node.Attributes.Remove("onBlur");
                node.Attributes.Remove("onClick");
                node.Attributes.Remove("onMouseOver");
                node.Attributes.Remove("onMouseOut");
                node.Attributes.Remove("onDoubleClick");
                node.Attributes.Remove("onLoad");
                node.Attributes.Remove("onUnload");
            }
        }

        // remove any style attributes that contain the word expression (IE evaluates this as script)
        nc = doc.DocumentNode.SelectNodes("//*[contains(translate(@style, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), 'expression')]");
        if (nc != null)
        {
            foreach (HtmlNode node in nc)
            {
                node.Attributes.Remove("stYle");
            }
        }

        return doc.DocumentNode.WriteTo();
    } 

4 个答案:

答案 0 :(得分:1)

我们遇到了同样的问题:用户输入HTML,我们希望在XHTML页面中显示它。请注意,它们输入HTML片段而不是完整文档。我在2010年对此进行了研究,使用单元测试来测试许多不同的情况。

解决方案:

  1. 使用Microsoft Anti-Cross Site Scripting Library删除所有内容 被认为是不安全的(主要是脚本)。请注意,此工具不会关闭这些标记:img,hr,br,有时它会以错误的顺序关闭标记。
  2. 使用Tidy.Net创建几乎有效的XHTML。
  3. 删除Tidy.Net倾向于创建的html,head和body标签。
  4. 删除Tidy.Net在“pre”标记内创建的额外换行符。
  5. 这将删除所有JS并创建在大多数情况下是有效的XHTML片段的东西。它还会删除所有样式标记。

    我尝试的工具存在以下问题:

    Microsoft反跨站点脚本库:不关闭这些标记:img,hr,br,有时它会以错误的顺序关闭标记。不幸的是不能定制。

    Tidy.Net:在预标记内创建额外的换行符。 (可以在运行工具后手动修复。)

    TidyForNet:不稳定。有时会给你“blabla.c中的Assertion faild”

    在VB6中制作的Tidy(C-DLL)COM包装器:至少可以说是不切实际的。您必须注册COM DLL。

    HtmlAgilityPack:偶尔插入额外的换行符。从预标签中删除换行符。

    Majestic12 HTML-parser:不关闭这些标记:img,hr,br,有时会以错误的顺序关闭标记。

    AntiSamy.Net:不切实际,因为它使用J#编写的组件已过时。因此,它无法在64位环境中运行。从好的方面来说,它可以自定义哪些标签和属性值。

答案 1 :(得分:0)

Encoder.HtmlEncode怎么样?在尝试使用AntiXss.HtmlEncode

时,VS 2010建议使用它

答案 2 :(得分:0)

字符串值=“ 此处警报('hello'),我们进入。请访问” +             “ http://west-wind.com'>西风网站。” +             “ http://west-wind.com/images/new.gif'/>”;             字符串safestring = Microsoft.Security.Application.Sanitizer.GetSafeHtmlFragment(value);

上面的代码将从字符串

中删除脚本标签

答案 3 :(得分:-2)

我会使用内置方法。在我看来,如果用户想破坏你的程序,他们会找到一种方法来实现它。但是,如果您结合使用多种方法来清理用户输入,那么您的程序将更加安全。

例如,使用名为“myString”的String变量,我会将REGEX字符剥离与手工剥离的常规手动字符结合起来,只是为了安全。

这将删除所有不是字母数字的内容。

myString = Regex.Replace(myString, "[^a-z0-9]", "", RegexOptions.CaseInsensitive);
myString = myString.replace("/","");
myString = myString.replace("<","");

您还可以通过删除介于“&lt;”之间的文本来进一步扩展此功能和“&gt;”字符然后在“&gt;”之间和“&lt;”。

我不想使用外部第三方库 - 除非我必须 - 因为你必须分发库,你依靠别人的程序来保证你的安全,如果他们的软件存在漏洞你的也很脆弱。