• ASP.NET MVC 3里面客户端输入验证的改动


    最近在用ASP.NET MVC 3,在通过TinyMCE HTML编辑器,向服务器端输入HTML代码时,收到了下面这个错误信息:

    异常详细信息: System.Web.HttpRequestValidationException: 从客户端(test="<a>adfasdf</a>")中检测到有潜在危险的 Request.Form 值。

    很明显,这是ASP.NET为了阻止跨站脚本攻击所实现的防御措施,然而在我的情况下,我的确需要ASP.NET临时关闭这个检查机制,因为这个时候我需要保存原始的HTML文本。在网上搜了一下,发现很多人的解决方案有点粗暴,要么是直接将整个站点的HTML跨站攻击检测机制禁止掉:

    1. web.config文件里,添加上<httpRuntime requestValidationMode="2.0" />
    2. 然后再<pages>节设置validateRequest="false" 禁用请求验证。

    安全一点的,也是把整个页面的检测机制禁止掉—即通过在webform页面的Page指令禁用请求验证,或在MVCController上加上[ValidateInput(false)]属性。下面这个razor语法的页面就可以让你重现这个问题:


    代码
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        
    <title>Sample Page</title>
    <script src="@Url.Content("~/Scripts/jquery-1.4.2.min.js")" type="text/javascript"></script>
        
    <script type="text/javascript" src="@Url.Content("~/Scripts/tinymce/tiny_mce.js")"></script>
        
    <script type="text/javascript" src="@Url.Content("~/Scripts/tinymce/jquery.tinymce.js")"></script>
        
    <script language="javascript" type="text/javascript">
            $(document).ready(
    function () {
                $(
    '#test').tinymce({
                    mode: 
    "textareas",
                    theme: 
    "simple"
                });
            });
        
    </script>
    </head>

    <body>
      
    <form method="post" action="">
        
    <label for="test">测试</label>
        
    <textarea name="test" id="test">
        
    </textarea>
        
    <br />
        
    <input type="submit" value="提交" />
      
    </form>
      
    <br />
      @if ( IsPost ) {
          
    <div>@Request["test"]</div>
      }
    </body>
    </html>


     

    MVC 3里,请求验证以及集成到HttpModule这一层了,也就是说,即使你用上面那两个方法,有可能还是禁用不了请求验证。这是因为上面两个方法是在处理Page的时候才有效,而HttpModulePage接收到请求之前就已经执行请求验证了。在MVC 3里,你可以告诉请求验证程序对一个字段忽略请求验证,但依然对其他字段执行请求验证。通过下面这条语句就可以指明你希望跳过验证的字段了—参数就是表单里输入控件的name属性值:


    @{    
        var text 
    = Request.Unvalidated().Form["test"];
    }


    另外,请注意Unvalidated这个函数,你只有在安装了WebMatrix Beta2以及ASP.NET MVC 3 RC后才有。

     

    装好WebMatrix Beta 2,再次访问网页,你就可以看到在test文本框里输入的html字符串可以正常通过验证,但是在其他文本框输入的html字符串则不能通过验证。

     

    但是,接下来又有另外一个问题,当你回显HTML字符串的时候,它并没有跟你想象的那样作为HTML代码插入,而被当作了普通文本输出,如下图:

     

    这是因为,在MVC 3Razor引擎里,默认情况下,所有的字符串都会先被转义以后才能输出,也就是说,下面这段代码:

    <div>text</div>

     

    实际上是被Razor引擎替换成下面的代码:

     

    <div>@Server.EncodeHtml(text)</div>

     

    如果你需要修改这个行为,应该将代码改成下面这样:

     

    var wrapper = new HtmlString(text);
    <div>@wrapper</div>

    下面是完整的代码(注意,你需要安装了WebMatrix Beta2以及ASP.NET MVC 3 RC才能顺利编译):

    代码
    @{    
        var text = Request.Unvalidated().Form["test"];
    }
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        
    <title>Sample Page</title>
        
    <script src="/Scripts/jquery-1.4.2.min.js" type="text/javascript"></script>
        
    <script type="text/javascript" src="/Scripts/tinymce/tiny_mce.js"></script>
        
    <script type="text/javascript" src="/Scripts/tinymce/jquery.tinymce.js"></script>
        
    <script language="javascript" type="text/javascript">
            $(document).ready(
    function () {
                $(
    '#test').tinymce({
                    mode: 
    "textareas",
                    theme: 
    "simple"
                });

            });
        
    </script>
    </head>

    <body>
      
    <form method="post" action="">
        
    <label for="test">测试</label>
        
    <textarea name="test" id="test">
        
    </textarea>
        
    <br />
        
    <input type="submit" value="提交" />
      
    </form>

      
    <br />
      @if ( IsPost ) {
          var wrapper = new HtmlString(text);
          
    <div>@wrapper</div>
      }
    </body>
    </html>


     

  • 相关阅读:
    leetcode刷题笔记 273题 整数转换英文表示
    leetcode刷题笔记 278题 第一个错误的版本
    leetcode刷题笔记 268题 丢失的数字
    leetcode刷题笔记 264题 丑数 II
    leetcode刷题笔记 263题 丑数
    20210130日报
    20210129日报
    20210128日报
    20210127日报
    20210126日报
  • 原文地址:https://www.cnblogs.com/killmyday/p/1879996.html
Copyright © 2020-2023  润新知