曬一下我的web過濾器

背景

  Xss跨站腳本的煩惱大部分程序員應該都碰到過,防不勝防。關於跨站的實例可以看這裏。如果在項目開發前期開始控制還容易點,但是如果是歷史項目還是相當龐大的,那麼你該糾結。本章給大家介紹一種解決方案。當然作爲過濾器本身不單單是防跨站的作用。


概述

  1.可以針對頁面、控件進行過濾正則的配置
  2.提交數據時提供post、get、head、cookies4種方式的過濾
  3.瀏覽頁面時提供服務器端控件的check,以及頁面輸出流的check和更新
  4.應用端生成詳細的Xss警報日誌 和異常日誌
  5.服務器端彙總一般的Xss警報以及用戶的輸入等
  6.IP黑白過濾


Demo概要流程

step.1 配置過濾類別 post get head cookies大家都懂的 other爲自定義擴展 outputcontrol爲服務器端控件檢查 outputhtml爲頁面輸出流

step.2 以get方式爲例 應用類型1表示get 過濾正則以未轉義的參考 因爲最後的配置媒介爲xml 至於原因 下面會描述  

step.3 根據配置類型設置參數 以post方式爲例 例如UserInfo.aspx頁面過濾Email,ICQ,QQ 默認過濾全部頁面 全部參數

step.4 在配置類別頁面生成Xml固化文本 這麼做的原因爲了減少主站的複雜度並且各個應用站點可以靈活擴展自己的特性 最主要的是忽略網絡傳輸異常的風險 畢竟安全的優先級最高

 step.5 應用端附加組件 關於組件下面概要設計中會詳細描述

step.6 看效果 簡單以get方式爲例

加些敏感字符 設置異常跳轉頁面爲http://t.163.com/notfound

敲下回車


 概要設計 

這套web過濾器還算不上系統的層級,主要是一個設計思路。我想很多同學在看完文章以後會有種恍然大悟的感覺,原來如此簡單。不錯,關心項目周邊的細節你還會發現很多有趣又有用的內容。.net項目的一個優勢就是在應用程序週期的大部分環節都可以很好的控制。對於上述功能可能會有很多同學想到AOP,但是AOP做不到通用。

下面爲大家揭開過濾器的真實面貌。

你沒看錯,確實只有這麼一些。

XssCheck負責實際的check動作。

例如白名單外的IP 惡意訪問超過5次以上 應用端緩存下記錄 應用端拒絕訪問12小時-跳轉頁面 不再彙總警報數據 惡意訪問5次,拒絕訪問跳轉至自定義的頁面。

根據不同的配置類型 進行不同的check動作

頁面輸出流的處理比較特殊 對於流的處理蟲子這裏分爲2類 是隻check還是包含更新操作 。這裏需要區分2個概念HttpModule和HttpHandler


 HttpModule msdn的原版解釋

An HTTP module is an assembly that is called on every request made to your application. HTTP modules are called as part of the ASP.NET request pipeline and have access to life cycle events throughout the request. HTTP modules therefore give you the opportunity to examine incoming and outgoing requests and take action based on the request. The topics in this section provide information on how HTTP modules work and how to create them.

一句話來說我們可以自定義編程HttpModule來實現對HttpRequest中的內容做一個處理或者過濾。也就是訂閱管線事件,並在事件處理器中執行所需的相關操作。

至於具體有哪些管線事件參考
http://msdn.microsoft.com/library/chs/default.asp?url=/library/CHS/cpref/html/frlrfsystemwebhttpapplicationclasstopic.asp

HttpHanlder msdn的原版解釋

 定義 ASP.NET 爲使用自定義 HTTP 處理程序同步處理 HTTP Web 請求而實現的協定。

一句話來HttpHandler是一個HTTP請求的真正處理中心,也正是在這個HttpHandler容器中,ASP.NET Framework才真正地對客戶端請求的服務器頁面做出編譯和執行,。

HttpModule 與HttpHanlder 的關係。

HttpHanlder 將處理過後的信息附加在HTTP請求信息流中再次返回到HttpModule中。

當一個HTTP請求經同HttpModule容器傳遞到HttpHandler容器中時,ASP.NET Framework會調用HttpHandler的Proce***equest成員方法來對這個HTTP請求進行真正的處理。以一個ASPX頁面爲例,正是在這裏一個ASPX頁面才被系統處理解析,並將處理完成的結果繼續經由HttpModule傳遞下去,直至到達客戶端。HttpHanlder 中的過渡方法爲PostRequestHandlerExecute。還想更詳細瞭解的同學可以參考msdn中ASP.NET的管道處理。


 瞭解到上述概念後,明白的同學應該瞭解到流的處理是在哪個階段了。因爲頁面輸出流已經是服務端處理完首次請求向客戶端發送數據的環節。這裏流的處理我們放在HttpHanlder中,如何在HttpModule中的BeginRequest管線事件中跳到Handler環節,這裏蟲子用了一個取巧方法,細心的同學已經發現了

 <add verb="*" path="*.xss.aspx" type="BBS.XssCheck.XssHandler,BBS.XssCheck" />

蟲子對URL進行了重寫,在第二次請求中組建會根據url直接pass掉其他管線方法直接到HttpHanlder中處理。具體處理過程就不贅述了。

還值得一說的地方就是對服務器端控件的check 服務器端的控件獲取方法

部分代碼 比較醜陋 現在懶得改了 喜歡編程之美的同學自己琢磨着改吧

 int nPageControls = page.Controls.Count;

            System.Collections.Specialized.NameValueCollection controlcollection = new System.Collections.Specialized.NameValueCollection();

            for (int i = 0; i < nPageControls; i++)
            {
                foreach (System.Web.UI.Control control in page.Controls[i].Controls)
                {
                    if (control is Button)
                    {
                        controlcollection.Add(control.ID, ((Button)control).Text);
                    }
                    else if (control is Label)
                    {
                        controlcollection.Add(control.ID, ((Label)control).Text);
                    }
                    else if (control is HtmlAnchor)
                    {
                        controlcollection.Add(control.ID, ((HtmlAnchor)control).HRef);
                    }
                    else if (control is TextBox)
                    {
                        controlcollection.Add(control.ID, ((TextBox)control).Text);
                    }
                    else if (control is HtmlImage)
                    {
                        controlcollection.Add(control.ID, ((HtmlImage)control).Src);
                    }
                    if (mode)
                    {
                        try
                        {
                            if (r.IsMatch(controlcollection[control.ID]))
                            {
                                XssLog(context, 5, control.ID, controlcollection[control.ID]);
                                break;
                            }
                        }
                        catch { }
                    }
                }
            }

 XssControl實現IHttpModule

get、post、head、cookies都在BeginRequest管線事件

 服務器端控件檢查是在PostRequestHandlerExecute管線事件

XssHandler實現IHttpHandler

XssWebUtils實現一些通用的web處理方法


大概如此了 歡迎有興趣的同學發表自己的觀點

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章