类似于这个问题,但我不太关心哪些字符会/不会引发错误。我更好奇的是,我可以调用什么方法来检查自己,如果当前字符串会触发上面的错误消息。
为了提供一些背景信息,当用户忘记密码并需要重置时,我会创建随机密码。不幸的是,随机密码生成器最近"意外"创建了一个包含&#
的密码生成器。当用户尝试登录时,这导致页面中断。
正如围绕这个主题的许多文章中所提到的,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; }