这组正则表达式是否完全防止跨站点脚本?

Cor*_*ger 6 regex security xss

下面的代码不会捕获什么危险的例子?

编辑:在一些评论后,我添加了另一行,评论如下.请参阅Vinko在David Grant的回答中的评论.到目前为止,只有Vinko回答了这个问题,该问题要求具体的例子可以通过这个功能.Vinko提供了一个,但我编辑了代码来关闭那个洞.如果你们中的另一个人能够想到另一个具体的例子,那么你们将得到我的投票!

public static string strip_dangerous_tags(string text_with_tags)
{
    string s = Regex.Replace(text_with_tags, @"<script", "<scrSAFEipt", RegexOptions.IgnoreCase);
    s = Regex.Replace(s, @"</script", "</scrSAFEipt", RegexOptions.IgnoreCase);
    s = Regex.Replace(s, @"<object", "</objSAFEct", RegexOptions.IgnoreCase);
    s = Regex.Replace(s, @"</object", "</obSAFEct", RegexOptions.IgnoreCase);
    // ADDED AFTER THIS QUESTION WAS POSTED
    s = Regex.Replace(s, @"javascript", "javaSAFEscript", RegexOptions.IgnoreCase);

    s = Regex.Replace(s, @"onabort", "onSAFEabort", RegexOptions.IgnoreCase);
    s = Regex.Replace(s, @"onblur", "onSAFEblur", RegexOptions.IgnoreCase);
    s = Regex.Replace(s, @"onchange", "onSAFEchange", RegexOptions.IgnoreCase);
    s = Regex.Replace(s, @"onclick", "onSAFEclick", RegexOptions.IgnoreCase);
    s = Regex.Replace(s, @"ondblclick", "onSAFEdblclick", RegexOptions.IgnoreCase);
    s = Regex.Replace(s, @"onerror", "onSAFEerror", RegexOptions.IgnoreCase);
    s = Regex.Replace(s, @"onfocus", "onSAFEfocus", RegexOptions.IgnoreCase);

    s = Regex.Replace(s, @"onkeydown", "onSAFEkeydown", RegexOptions.IgnoreCase);
    s = Regex.Replace(s, @"onkeypress", "onSAFEkeypress", RegexOptions.IgnoreCase);
    s = Regex.Replace(s, @"onkeyup", "onSAFEkeyup", RegexOptions.IgnoreCase);

    s = Regex.Replace(s, @"onload", "onSAFEload", RegexOptions.IgnoreCase);

    s = Regex.Replace(s, @"onmousedown", "onSAFEmousedown", RegexOptions.IgnoreCase);
    s = Regex.Replace(s, @"onmousemove", "onSAFEmousemove", RegexOptions.IgnoreCase);
    s = Regex.Replace(s, @"onmouseout", "onSAFEmouseout", RegexOptions.IgnoreCase);
    s = Regex.Replace(s, @"onmouseup", "onSAFEmouseup", RegexOptions.IgnoreCase);
    s = Regex.Replace(s, @"onmouseup", "onSAFEmouseup", RegexOptions.IgnoreCase);

    s = Regex.Replace(s, @"onreset", "onSAFEresetK", RegexOptions.IgnoreCase);
    s = Regex.Replace(s, @"onresize", "onSAFEresize", RegexOptions.IgnoreCase);
    s = Regex.Replace(s, @"onselect", "onSAFEselect", RegexOptions.IgnoreCase);
    s = Regex.Replace(s, @"onsubmit", "onSAFEsubmit", RegexOptions.IgnoreCase);
    s = Regex.Replace(s, @"onunload", "onSAFEunload", RegexOptions.IgnoreCase);

    return s;
}
Run Code Online (Sandbox Code Playgroud)

Kor*_*nel 48

它永远不够 - 白名单,不要黑名单

例如,javascript:伪URL可以使用HTML实体进行模糊处理,您已经忘记了<embed>,behavior并且expression在IE中存在危险的CSS属性.

无数种方法来逃避过滤器,这种方法必将失败.即使您今天发现并阻止了所有可能的漏洞利用,未来也可能会添加新的不安全元素和属性.

保护HTML只有两种好方法:

  • 将其转换通过替换每个文本<&lt;.
    如果您想允许用户输入格式化文本,您可以使用自己的标记(例如像SO那样的降价).

  • 将HTML解析为DOM,检查每个元素和属性,并删除未列入白名单的所有内容.
    您还需要检查允许的属性的内容,例如href(确保URL使用安全协议,阻止所有未知协议).
    一旦清理了DOM,就可以从中生成新的有效HTML.永远不要像在文本上那样处理HTML,因为无效的标记,注释,实体等很容易欺骗你的过滤器.

还要确保您的页面声明其编码,因为有利用浏览器自动检测错误编码的漏洞.


cee*_*yoz 10

你好得多熄灭后,再全部<&lt;和所有>&gt;,然后转换可接受标签背面.换句话说,白名单,不要列入黑名单.


Vin*_*vic 7

正如David所说,没有简单的方法来保护只有一些正则表达式,你总是可以忘记一些东西,比如javascript:在你的情况下.您最好在输出时转义HTML实体.有很多关于最佳方法的讨论,取决于你实际需要允许的内容,但可以肯定的是你的功能还不够.

杰夫在这里谈了这个.