如何检查字符串是否会引发“一个潜在危险的请求.检测到窗体值…”错误



类似于这个问题,但我不太关心哪些字符会/不会引发错误。我更好奇的是,我可以调用什么方法来检查自己,如果当前字符串会触发上面的错误消息。

为了提供一些背景信息,当用户忘记密码并需要重置时,我会创建随机密码。不幸的是,随机密码生成器最近"意外"创建了一个包含&#的密码生成器。当用户尝试登录时,这导致页面中断。

正如围绕这个主题的许多文章中所提到的,ValidateRequest=false(或适用于.NET 4.0的<httpRuntime requestValidationMode="2.0" />)可以用来关闭.NET对这些漏洞的检查,但当我首先创建字符串时,我看不出有任何理由失去这一额外的安全层。简单地告诉随机生成器在一个不完整的列表(<&#等)上重新随机化似乎不是最干净的解决方案,所以我想使用相同的方法来检查.NET是否在使用。

微软解释了哪些漏洞是有问题的,以及正在采取什么措施来防范这些漏洞。

这家伙谈到在使用Reflector后找到了一个名为IsDangerousString的函数,但我找不到这个函数来使用它。他还提到了.NET 1.1,我正在使用.NET 3.5

验证请求的ASP.NET类是System.Web.CrossSiteScriptingValidation,您需要的方法是IsDangerousString。不幸的是,两者都标记为internal,因此您无法直接访问它们。你有几个选择:

选项1:通过反射调用IsDangerousString。然而,微软可以随时更改方法,这会破坏你的应用程序。

选项2:解压缩IsDangerousString并将其复制到您自己的应用程序中。请参阅下面的代码。

选项3:致电Membership.GeneratePassword。这将返回一个保证通过请求验证的密码。

ASP.NET CrossSiteScriptingValidation类的摘录(通过.NET反射器):

private static char[] startingChars = new char[] { '<', '&' };
internal static bool IsDangerousString(string s, out int matchIndex)
{
    matchIndex = 0;
    int startIndex = 0;
    while (true)
    {
        int num2 = s.IndexOfAny(startingChars, startIndex);
        if (num2 < 0)
        {
            return false;
        }
        if (num2 == (s.Length - 1))
        {
            return false;
        }
        matchIndex = num2;
        char ch = s[num2];
        if (ch != '&')
        {
            if ((ch == '<') && ((IsAtoZ(s[num2 + 1]) || (s[num2 + 1] == '!')) || ((s[num2 + 1] == '/') || (s[num2 + 1] == '?'))))
            {
                return true;
            }
        }
        else if (s[num2 + 1] == '#')
        {
            return true;
        }
        startIndex = num2 + 1;
    }
}
private static bool IsAtoZ(char c)
{
    return (((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')));
}

基于@Michael Liu答案中选项2的Javascript函数:

function isDangerousString(s) { return s.match(/<[a-zA-Z!/?]|&#/) !== null; }

最新更新