[英]Asp.net automatically blocks any input that resembles html code
我使用 asp.net/visual studio2013/c# 创建一个 web 应用程序。
我有一个输入文本框。 当我输入<div>
(或任何类似 html 的无意义标签,例如<abc>
)并执行回发时,回发永远不会发生,并且我收到一条 javascript 错误消息:
Sys.WebForms.PageRequestManagerServerErrorException:
A potentially dangerous Request.Form value was detected from the client
(ctl00$ctl00$MainSection$DescriptionTextBox="<div>").
此错误是由一个大 javascript 文件生成的,该文件在我构建应用程序时会自动插入到我的页面中。 (换句话说,我无法控制这个 javascript)
这对于防止黑客在我的代码中注入任何代码非常有用,但真正困扰我的是实际上没有发生回发,也没有显示任何错误消息或任何内容。
想象一个随机用户试图在文本框中键入<for my best friend>
。 从用户的角度来看,网站被破坏了,因为什么都没有发生。
我的问题是,当问题出现时,我如何通知用户问题是什么(即您无法输入该文本)?
当然是出于安全原因。
这是一个解释和解决方法:
我不建议在整个站点上完全关闭它,因为它是您真正想要保留的主要安全功能。
在提交之前使用javascript客户端并在加载页面时将其恢复正常要好得多。
举个例子, TinyMCE 有一个用于此目的的 onSubmit() 事件方法:
你可以钩住它,并用一个单行替换<
和>
用它们对 HTML 友好的对应物<
和>
.
对于其他控制,应该有相同的机制。
当您确定您将字符串传递给 HTML 的任何地方都进行了 HTML 编码时,然后设置validateRequest="false"。
在 .NET 4 中,您可能需要做更多的工作。 有时还需要在 web.config 中添加httpRuntime requestValidationMode="2.0"
如果您使用的是 MVC,则在模型属性上使用[AllowHtml] 。
不久前我写了一个 NuGet 包,它禁用了网站的请求验证批发。 听起来你的场景可能是这个的候选者。
请求验证是(事后看来)一个计划不周的功能,我们试图抓住开发人员的手并自动保护他的站点免受 XSS 攻击。 不幸的是,它实际上并没有那么好用,但由于人们依赖它,我们不能在默认情况下简单地在产品中关闭该功能。 :(
如果您确实安装了此软件包,请检查以确保您正在验证/清理所有输入并正确编码所有输出。
请按照以下步骤操作,
1.阅读这里后根据您的需要在任何地方禁用请求验证
2.然后添加这个静态方法,它可以检测请求中的HTML标签。
internal static class CrossSiteScriptingValidation
{
private static char[] startingChars = new char[2]
{
'<',
'&'
};
static CrossSiteScriptingValidation()
{
}
private static bool IsAtoZ(char c)
{
if ((int) c >= 97 && (int) c <= 122)
return true;
if ((int) c >= 65)
return (int) c <= 90;
else
return false;
}
internal static bool IsDangerousString(string s, out int matchIndex)
{
matchIndex = 0;
int startIndex = 0;
while (true)
{
int index = s.IndexOfAny(CrossSiteScriptingValidation.startingChars, startIndex);
if (index >= 0 && index != s.Length - 1)
{
matchIndex = index;
switch (s[index])
{
case '&':
if ((int) s[index + 1] != 35)
break;
else
goto label_7;
case '<':
if (CrossSiteScriptingValidation.IsAtoZ(s[index + 1]) || (int) s[index + 1] == 33 || ((int) s[index + 1] == 47 || (int) s[index + 1] == 63))
goto label_5;
else
break;
}
startIndex = index + 1;
}
else
break;
}
return false;
label_5:
return true;
label_7:
return true;
}
}
3.在你的代码隐藏中调用上面的方法来像这样手动验证表单值,
int invalidTagIndex =0;
CrossSiteScriptingValidation.IsDangerousString( value, out invalidTagIndex);
并基于验证重定向到错误页面或按照任何方式向用户指示错误。 这一步是必需的,因为简单地关闭请求验证可能会对您的站点造成 XSS 威胁。
我对此的想法有点不同。 在将数据发送到服务器之前使用 javascript 解析数据,并在服务器端将其转换回正常状态。 这样做可以让您保持构建的安全性。
JavaScript: encodeURI("<test>")
等于: "%3Ctest%3E"
要么将其存储在您的数据库中,要么使用 .net Server.UrlDecode(text)
将其转换回来
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.