Asp.net会自动阻止任何类似html代码的输入

时间:2014-02-03 14:34:57

标签: c# javascript asp.net

我使用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>。从用户的角度来看,网站已被破坏,因为没有任何反应。

我的问题是,当出现问题时,如何告知用户问题是什么(即,您无法输入该文本)?

5 个答案:

答案 0 :(得分:2)

确实是出于安全原因。

以下是解释和解决方法:

Rick Strahl's blog

我不建议在整个网站上完全切换它,因为它是您真正想要保留的主要安全功能。

最好在提交之前使用javascript客户端,并在加载页面时将其恢复正常。

仅作为示例,TinyMCE has an onSubmit() event方法用于此目的:

您可以加入其中并使用一行代替<>与他们的HTML友好对应&lt;&gt;

对于其他控制,应该有相同的机制。

答案 1 :(得分:2)

如果您确定在任何地方进行HTML编码,则将字符串传递给HTML,然后设置 validateRequest =“false”。

在.NET 4中,您可能需要做更多的事情。有时需要添加 httpRuntime requestValidationMode =“2.0”  到web.config

Reference

如果您使用的是MVC,请在模型属性中使用 [AllowHtml]

答案 2 :(得分:1)

我前一段时间写了a NuGet package,禁用了网站的请求验证批发。听起来你的情景可能是这个的候选人。

请求验证(事后看来)是一个计划不周的功能,我们试图抓住开发人员的手并自动保护他的网站免受XSS攻击。不幸的是,它实际上并没有那么好,但由于人们依赖它,我们不能简单地在产品中关闭该功能。 :(

如果您确实安装了此软件包,请检查以确保您正在验证/清理所有输入并正确编码所有输出。

答案 3 :(得分:0)

请按照以下步骤进行操作

1.阅读here

后,根据您的需要在任何地方禁用请求验证

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威胁。

答案 4 :(得分:0)

我对此有一点不同。使用javascript解析数据,然后再将其发送到服务器,并在服务器端将其转换回正常状态。这样可以使构建保持安全性。

JavaScript:encodeURI("<test>")

等于:"%3Ctest%3E"

将其存储在数据库中或使用.net将其转换回 Server.UrlDecode(text)