zoukankan      html  css  js  c++  java
  • 利用 HttpModule,基于输出,统一控制、干预、处理(例如: 过滤关键字、AntiXSS) ASP.Net WebForm Control 展现属性的方案原型

    
    /*
    利用 HttpModule 统一干预、处理(例如: 过滤关键字) ASP.Net WebForm Control 的输出渲染
    前几天在阅读老赵的《一个较完整的关键字过滤解决方案》上中下,
    http://www.cnblogs.com/JeffreyZhao/archive/2008/12/22/filter-forbidden-word-solution.html
    当时提出了一个在 HttpModule "输出流"中转"字符串"后利用"替换",实现"基于输出干预处理"的过滤方案,
    《HttpModule 实现 ASP.Net (*.aspx) 中文简繁体的自动转换,不用修改原有的任何代码,直接部署即可!》
    http://microshaoft.cnblogs.com/archive/2005/12/03/289665.html
    我也承认那个方案是有性能问题的。
    最近在想一个实现全局解决"跨站脚本攻击"的统一通用干预处理,实现安全输出的方案。
    "跨站脚本攻击"的一般解决方案就是在"输出"时,也就是先做"HTML/JavaScript Encode",然后输出 Safe Html/JavaScript。
    ASP.Net WebControl 及其属性,有很多其实都不会自动 Encode 后输出的,即不是天然免疫 XSS Attack 的
    《What's wrong with ASP.NET? HTML encoding》
    http://msmvps.com/blogs/calinoiu/archive/2006/06/13/102957.aspx
    《Which ASP.NET Controls Automatically Encodes?》
    https://blogs.msdn.com/sfaust/archive/2008/09/02/which-asp-net-controls-automatically-encodes.aspx
    《下面是一个很全的 "不安全控件及属性" 的 "黑名单"》
    https://blogs.msdn.com/sfaust/attachment/8918996.ashx
    我的方案目前还只是一个原型
    就是只将 ASP.Net WebForm Sever WebControl/HtmlControl 的一些与"文本展现或输出"相关的属性统一处理的方案
    目前在遍历所有控件的过程中,利用反射(性能)只处理了
    System.Web.UI.WebControls 命名空间下的控件的"Text"属性
    System.Web.UI.HtmlControls 命名空间下的控件的"Value"属性
    发现天然能够干预处理程序代码动态 Add 的 Control
    漏处理了其他命名的展现相关属性
    而且还有一些过多处理了 WebForm Page 默认自动添加的控件的情况,因此还很不完善。
    不能处理其他形式的 Response 输出(例如: Response.Write、前代码的<%= 后代码类成员变量%>),
    自定义的 UserControl、WebCustomControl 的控件如果非"Text"或"Value"命名的展现属性也无法处理,
    当然也有可能误伤与展现无关的"Text"或"Value"属性。
    该方案逐步完善后,理论上,应该能"忽略"掉不必处理的控件及属性,而且还要按不安全"控件及其属性"的各种情况,分别处理,还是有一定的工作量。
    另外性能尚未评估,遍历控件可能存在一定瓶颈,
    其实我认为使用 HttpModule.dll、HttpHandler.dll、Global.asax 本身也存在一些性能瓶颈,因为所有的请求与输出都要流经此处。
    以下完整代码
    ControlsPropertyFilterHttpModule.cs
    web.config
    test.aspx (注意有XSS Attack 测试代码,不必惊慌只是 alert)
    */
    //ControlsPropertyFilterHttpModule.cs
    namespace Microshaoft
    {
        using System;
        using System.Web;
        using System.Web.UI;
        using System.Reflection;
        public class ControlsPropertyFilterHttpModule : IHttpModule
        {
            private HttpApplication _contextApplication;
            public void Init(HttpApplication context)
            {
                _contextApplication = context;
                _contextApplication.PostMapRequestHandler += new EventHandler(_contextApplication_PostMapRequestHandlerProcess);
            }
            public void Dispose()
            {
                _contextApplication = null;
                _contextApplication.Dispose();
            }
            public void _contextApplication_PostMapRequestHandlerProcess(object sender, EventArgs e)
            {
                IHttpHandler handler = null;
                if (_contextApplication == null)
                {
                    return;
                }
                if (_contextApplication.Context.Handler is Page)
                {
                    handler = _contextApplication.Context.Handler;
                }
                if (handler != null)
                {
                    Page page = handler as Page;
                    //page.PreRender += new EventHandler(page_PreRender);
                    page.PreRenderComplete += new EventHandler(page_PreRender);
                }
            }
            private void page_PreRender(object sender, EventArgs e)
            {
                Page page = sender as Page;
                ControlCollection cc = page.Controls;
                RecursiveProcessControls(cc);
            }
            private static void RecursiveProcessControls(ControlCollection cc)
            {
                foreach (Control c in cc)
                {
                    Type t = c.GetType();
                    //需要按控件种类分情况处理各种文本显示相关的属性
                    //目前只处理 Text 和 Value 属性
                    PropertyInfo pi = t.GetProperty("Text"); //Server WebControls
                    if (pi != null)
                    {
                        string s = (string) (pi.GetValue(c, null));
                        s = string.Format("Microshaoft处理了[{0}]", s);
                        //s = HttpUtility.HtmlEncode(s); //AntiXSS
                        pi.SetValue(c, s, null);
                    }
                    pi = t.GetProperty("Value"); //Server HtmlControls
                    if (pi != null)
                    {
                        string s = (string) (pi.GetValue(c, null));
                        s = string.Format("Microshaoft处理了[{0}]", s);
                        //s = HttpUtility.HtmlEncode(s); //AntiXSS
                        pi.SetValue(c, s, null);
                    }
                    if (c.HasControls())
                    {
                        RecursiveProcessControls(c.Controls);
                    }
                }
            }
        }
    }
    
    
    
    //test.aspx
    <%@ Page language="c#" AutoEventWireup ="true"%>
    <%@ Import Namespace="System.Data" %>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
    <HTML>
        <HEAD>
            <title>WebForm1</title>
            <meta name="generator" content="editplus" />
            <meta name="author" content="" />
            <meta name="keywords" content="" />
            <meta name="description" content="" />
        <script language="C#" runat="server">
        protected void Page_Load(object sender, EventArgs ea) 
        {
            h1.Text += "<script>alert('HL Xss Attack')" + "</scr" + "ipt>";
            DataTable dt = MakeTable("F1","F2");
            string expression = "1 = 1 or f1 = '2'"; 
            DataView dv = dt.DefaultView; 
            dv.Sort = "f1 desc"; 
            dv.RowFilter = expression; 
            datagrid1.DataSource = dv;
            datagrid1.DataBind();
            gridview1.DataSource = dv;
            gridview1.DataBind();
            TextBox tb = new TextBox();
            tb.Text = "动态 TextBox";
            p1.Controls.Add(tb);
        }
        void datagrid1_ItemDataBound(object sender, DataGridItemEventArgs e) 
        {
    ///        foreach (TableCell cell in e.Item.Cells)
    ///        {
    ///            if (cell.Text != string.Empty)
    ///            {
    ///                cell.Text = HttpUtility.HtmlEncode(cell.Text);
    ///            }
    ///        }
        }
        void gridview1_RowDataBound(object sender, GridViewRowEventArgs e) 
        {
    ///        foreach (TableCell cell in e.Row.Cells)
    ///        {
    ///            if (cell.Text != string.Empty)
    ///            {
    ///                cell.Text = HttpUtility.HtmlEncode(cell.Text);
    ///            }
    ///        }
        }
        private static DataTable MakeTable
                            (
                                string c1Name
                                , string c2Name
                            )
        {
            DataTable table= new DataTable();
            DataColumn column = new DataColumn(c1Name, typeof(int));
            table.Columns.Add(column);
            column = new DataColumn(c2Name, typeof(string));
            table.Columns.Add(column);
            table.Rows.Add(1,"<script>alert('datagrid xss attack')</scr" + "ipt>");
            table.Rows.Add(2, "\u003c" + "scr" + "ipt\u003ealert\u0028\u0022gridview XSS \u0041ttack\u0022\u0029\u003c/script\u003e");
            return table;
        }
        </script>
        </HEAD>
        <body MS_POSITIONING="GridLayout">
            <form id="Form1" method="post" runat="server">
                <asp:TextBox ID="tb1" Text="静态 textBox" runat="server" />
                <asp:Label ID="l1" Text="静态 label" runat="server" />
                <asp:Panel id="p1" runat="server"/>
                <asp:Hyperlink ID="h1" NavigateUrl="http://www.baidu.com" runat="server">
                        百度 Hyperlink<script>alert('HL Xss Attack')</script>
                </asp:Hyperlink>
                <input ID="Value2" Type="Text" Value="静态 HtmlControls HtmlInputText" runat="server"/>
                <asp:ListBox ID="lb1" Width="" runat="server">
                    <asp:ListItem><script>alert('LB Xss Attack')</script></asp:ListItem>
                    <asp:ListItem></asp:ListItem>
                </asp:ListBox>
                <ASP:DataGrid ID="datagrid1" runat="server"
                    AutoGenerateColumns="True"
                    OnItemDataBound = "datagrid1_ItemDataBound"
                />
                <ASP:GridView ID="gridview1" runat="server"
                    AutoGenerateColumns="True"
                    OnRowDataBound = "gridview1_RowDataBound"
                />
            </form>
        </body>
    </HTML>
    
    
  • 相关阅读:
    Java实现 LeetCode 400 第N个数字
    Java实现 LeetCode 400 第N个数字
    Java实现 LeetCode 399 除法求值
    Java实现 LeetCode 399 除法求值
    Java实现 LeetCode 399 除法求值
    Java实现 LeetCode 398 随机数索引
    Java实现 LeetCode 398 随机数索引
    Java实现 LeetCode 398 随机数索引
    linux中的cd ..和cd -命令有什么区别?
    GCC使用
  • 原文地址:https://www.cnblogs.com/Microshaoft/p/1371475.html
Copyright © 2011-2022 走看看