这可以改善吗?擦除危险的html标签

时间:2010-06-10 22:53:13

标签: c# .net javascript security

我一直在发现,对于我认为非常重要的东西,关于如何处理这个问题的信息或库很少。

我在搜索时发现了这一点。我真的不知道黑客可以尝试插入危险标签的百万种方式。

我有一个丰富的html编辑器,所以我需要保留非危险的标签,但要删除不好的标签。

这个脚本遗漏了什么吗?

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

修改

有2人建议白名单。我实际上喜欢白名单的想法,但从来没有真正做到这一点,因为没有人能真正告诉我如何在C#中做到这一点我甚至无法真正找到如何在c#中做到的教程(我最后一次看。我会再检查一下。)

  1. 如何制作白名单?它只是一个列表集合吗?

  2. 您如何实际解析所有html标签,脚本标签和其他所有标签?

  3. 一旦你有了标签,你如何确定允许哪些标签?将它们与列表集合进行比较?但是如果内容进来并且有100个标签并且你有50个允许的话会发生什么。您需要将这100个标记中的每一个与50个允许的标记进行比较。这很有意义,可能会很慢。

  4. 找到无效标签后如何将其删除?如果发现一个标签无效,我真的不想拒绝一整套文本。我宁愿删除并插入其余部分。

  5. 我应该使用html敏捷包吗?

2 个答案:

答案 0 :(得分:4)

该代码很危险 - 您应该将列入白名单元素,而不是将它们列入黑名单。

换句话说,制作一个你想要允许的标签和属性的小列表,不要让任何其他人通过。

编辑:我不熟悉HTML敏捷包,但我认为没有理由不这样做。由于我不了解该框架,因此我会为您提供伪代码

doc.LoadHtml(html);

var validTags = new List<string>(new string[] {"b", "i", "u", "strong", "em"});

var nodes = doc.DocumentNode.SelectAllNodes();
foreach(HtmlNode node in nodes)
    if(!validTags.Contains(node.Tag.ToLower()))
        node.Parent.ReplaceNode(node, node.InnerHtml);

基本上,对于每个标记,如果它不包含在白名单中,请将标记替换为其内部HTML。再说一遍,我不知道你的框架,所以我真的不能给你具体细节,对不起。希望这能让你开始朝着正确的方向前进。

答案 1 :(得分:3)

是的,我已经看到你错过了mousedown,onmouseup,onchange,onsubmit等。这是为什么应该为标签和属性使用白名单的一部分。即使你现在有一个完美的黑名单(非常不可能),标签和属性也经常被添加。

请参阅Why use a whitelist for HTML sanitizing?