程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> .NET實例教程 >> 從攻擊看設計

從攻擊看設計

編輯:.NET實例教程

前幾天,我們的站點的速度忽然慢了下來,接著發生了當機,重新啟動後最初訪問不錯,不久又慢了下來,數據庫服務器方面沒有顯示有什麼巨大壓力,並且在網站根目錄下創建一個靜態文件,居然訪問速度也奇低,由於網站最近正在更新,所以懷疑是不是邏輯有什麼問題,然而和同事交流發現最近並沒有更新關鍵的邏輯,在排除這種可能性後,焦點集中到了攻擊上

可是web服務器端統計數據顯示也沒有很大的壓力,正納悶的時候,回去想看郵箱裡的錯誤報告(這是由程序把所有黃頁錯誤自動轉發過來的),由於網站經常會被各種程序掃描,掃描會造成許多無法訪問的路徑錯誤,加上訪問超時等,這種報告每天都會有7-800封,所以一般都忽略掉:),而今天由於網站奇慢,錯誤報告瞬間超過了5000多封,郵箱已經無法打開,後來據同事說,整個公司的郵件服務器都當掉,所以只好請運維人員清空了我們郵箱

幸好本地的outlook中還保留了一些發生問題最初時候的錯誤郵件,發現有很多outofmemory錯誤,都是由一種特定的操作引起的(不妨稱為A操作)而這種錯誤本身並不能解釋問題,因為發生錯誤的模塊是分布在和服務器不同的另外一台機器上,去查了以下這個操作涉及的資源,(下稱為資源B)發現這個資源由於被反復增加內容而巨大無比,而對這種資源的操作成本是和資源的大小成比例的,而且調用是同步而非異步,也就是雖然整個對資源的操作過程是在另外一台機器上,但是調用端會一直阻塞等到操作完畢(或者超時)才會退出

這就造成請求排隊的原因.

攻擊者就是利用A操作沒有時間間隔的限制,反復調用,而使得網站癱瘓

整理邏輯發現,A操作首先是向數據庫中插入一條數據,然後更新資源B,開始時候B不大,而由於請求頻繁,數據庫的壓力大,請求可能有一些排隊,但是網站還可以承受,後來隨著B資源的增大,請求開始排隊,這時反而數據庫的壓力反而小了,因為請求都堆在了對資源B的操作上

再次重啟動服務後,果然看到了這個現象,發現數據庫開始壓力很大(由於B資源已經無法操作,大概攻擊這開始操作其他的資源)

我們在解決的時候,首先在數據庫端對A操作加上了時間間隔,數據庫的壓力立刻降低,然而請求依然排隊,最後在前端也加入了限制,解決了這個問題

對這個問題進行總結


盡量使用異步調用,同步調用一定要注意超期時間:可以看到,雖然對B資源使用了分布式技術,但是由於其是同步調用,並且超期時間沒有設置,所以實際沒有利用到分布的優勢。

限制操作的間隔時間和處理時間:每次請求處理的時間(包括成功和不成功)如果大於請求間隔時間,就會排隊,適當的排隊沒有問題,就好象我們排隊買火車票,雖然隊很長,但是只要大家都有票,(當然,訪問網站不會象買排隊火車票一樣有耐性),可是當有許多惡意請求參與排隊,比如買票時候前面總是有很多黃牛:),所以我希望有一天所有售票員都可以識別所有的黃牛,等他走到授票窗口前的時候,授票員就直接告訴他,“滾”,這樣就省去了他買票,後面等待的時間

所以要想辦法減低惡意請求的處理時間,一方面是要識別他們,另外就是如果是惡意請求,就要盡快的返回,能夠盡量在前端判斷就在前端判斷,能多早判斷就多早判斷,盡量不要拖到數據層。比如在解決這個問題時,我們就認為1秒內兩次執行A操作為惡意操作,並且對時間間隔的判斷在請求一開始就執行。

保護好復雜的邏輯:由於網站業務邏輯日趨復雜,許多操作都會涉及很多資源,這會給攻擊者造成機會,所以大家在設計這些極端復雜操作時要盡量想到上面的問題

不要忽略錯誤報告:無論錯誤報告有多長,請不要輕易刪除他們,因為他們永遠可能是你找到問題的鑰匙

 
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved