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>
    
    
  • 相关阅读:
    [ Python入门教程 ] Python文件基本操作
    [转载] 完整诠释软件质量模型
    [ Python入门教程 ] Python 数据结构基本操作
    [ Python入门教程 ] Python字符串数据类型及基本操作
    Notepad++好用的功能和插件
    Python在cmd上打印彩色文字
    你若读书,风雅自来
    [ 转载 ] ssh连接远程主机执行脚本的环境变量问题
    Python基本模块介绍:sys、platform
    深入解析跨站请求伪造漏洞:原理剖析
  • 原文地址:https://www.cnblogs.com/Microshaoft/p/1371475.html
Copyright © 2011-2022 走看看