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

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

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

我知道您可以使用正则表达式,但我也知道人们可以通过多种方式编写他们的脚本标签,以至于您可以欺骗正则表达式认为它是可以的。

我也听说了HTML Agility Pack很好,所以我想知道是否有专门为它制作的脚本删除类?

编辑

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

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

Great example (almost), Thanks! A few ways to make it stronger that I saw, though:

1) Use case-insensitive search when looking for links with "javascript:", "vbscript:", "jscript:". For example, the original example would not remove the HTML:

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

2) Remove any style attributes that contain an expression rule. Internet Explorer evaluates the CSS rule express as script. For example, the following would product a message box:

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

3) Also remove tags

I honestly have no idea why "expression" has not been removed from IE - major flaw in my opinion. (Try the div example in internet explorer and you'll see why - even IE8.) I just wish there was an easier/standard way to clean-up html input from a user.

这是经过这些改进后更新的代码。如果您发现任何错误,请告诉我:

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

最佳答案

我们遇到了同样的问题:用户输入 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”标签内创建的额外换行符。

这将删除所有 JS 并创建在大多数情况下是有效的 XHTML 片段的内容。它还将删除所有样式标签。

我试过的工具有这些问题:

Microsoft Anti-Cross Site Scripting Library: 不关闭这些标签:img、hr、br,有时它会以错误的顺序关闭标签。遗憾的是无法定制。

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

TidyForNet: 不稳定。有时会给你“断言在 blabla.c 中失败”

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

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

Majestic12 HTML 解析器: 不关闭这些标签:img、hr、br,有时它会以错误的顺序关闭标签。

AntiSamy.Net: 不切实际,因为它使用用已过时的 J# 编写的组件。因此它不能在 64 位环境中运行。从好的方面来说,关于允许哪些标签和属性值是非常可定制的。

关于c# - 如何删除危险字符(即脚本标签)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2962038/

相关文章:

c# - 在运行时编译 C# 代码 [更新 : or Alternatives]

c# - XAML 中的颜色反转

c# - 将 IP 异常(exception)添加到防火墙

c# - 获取包含枚举值的整数表示的字符串

.net - 了解 .Net 4.6 和 4.6.2 之间的差异/变化

.net - WPF 用户控件不随主窗口调整大小

javascript - Twilio 使用 PFcloud 发送批量消息时出错

C# Regex 将 aabbccddeeff 匹配为两个 aabbcc 和 ddeeff 集

javascript - 删除索引网站的代码历史?可能的?

javascript - 如何在 javascript 中创建模型以确保所有属性都存在