web安全漏洞之CSRF

一.CSRF(跨站請求攻擊)攻擊的原理:

1.攻擊原理:

  1. 網站使用cookie來存放用戶的登陸憑證
  2. cookie會在同源的http請求中自動攜帶

2.基本攻擊過程:

  1. 用戶登陸了受信任網站A,並在本地生成網站A的cookie
  2. 不登出網站A(A網站的cookie還有效),訪問了危險網站B
  3. 危險網站B裏面隱藏了一些訪問A的接口,用戶在訪問B網站的時候,就會不自覺的去調用訪問A網站的接口,這時候由於A網站的cookie還有效,因此危險網站B裏面隱藏的對A的接口就能訪問成功

二.CSRF攻擊示例:

1.示例:

  • 例如,aaa.com這個網頁都是經過session_id來記錄用戶的登陸狀態的
  • aaa.com頁面上有一個對做品點讚的功能,點贊提交地址爲aaa.com/api.like?id=777
  • 小明已經登陸了ww.aaa.com,天然aaa.com這個網站就會將小明的登陸狀態session_id存在cookie
  • 黑客本身建立了另一個網站bbb.com,並在頁面中放了這樣一個元素<img src="aaa.com/api.like?id=888">,這樣的話,一旦用戶進入這個bbb.com頁面,就會請求aaa.com這個網站的點贊接口aaa.com/api.like?id=888,並且點讚的用戶對象是888
  • 小明登陸了aaa.com,且代表身份信息的cookie尚未失效
  • 最後由於小明的登陸信息還沒有過時,訪問時就會帶上aaa.com的cookie(該過程詳見 這裏),那就等於給id爲888這個做品點讚了

image

2.常見的CSRF攻擊手段總結:

  1. 欺騙受害用戶完成該用戶權限許可的任意操做,例如:
    • 獲取用戶的隱私數據——誘騙用戶調用獲取隱私數據的接口
    • 更改用戶帳號的內容——誘騙用戶調用修改帳號信息的接口
    • 購物消費——誘騙用戶調用消費接口
    • ...
  2. 配合其餘漏洞攻擊
  3. CSRF蠕蟲——即產生蠕蟲效果,使CSRF攻擊一傳十,十傳百
    • 示例:有一個聊天網站A,它的 ++獲取好友列表接口++ 和 ++私信好友接口++ 都存在CSRF漏洞,攻擊者能夠將其組合成一個CSRF蠕蟲:
      • 用戶已經登陸了網站A,且不登出
      • 黑客發佈一個危險網站B,用戶訪問時,就會被誘騙訪問獲取好友列表接口,獲取好友的信息
      • 而後再利用私信好友的漏洞,誘騙用戶給每一個好友發送指向網站B的信息
      • 只要有好友查看了這條私信信息裏面的連接,CSRF蠕蟲就會不斷的傳播下去

三.CSRF的接口攻擊類型:

CSRF不只針對GET請求,其餘的類型的請求均可被利用來攻擊php

1.GET類型(最簡單的)

  1. 方式1:藉助一些自動發起請求的元素
    • 例如,在訪問含有這個img的頁面後,成功向http://wooyun.org/csrf?xx=11 發出了一次HTTP請求
// 只要設置這個圖片的寬高爲0,用戶是根本感受不到這個`<img>`元素存在
<img src=http://wooyun.org/csrf?xx=11 /> 
複製代碼
  1. 方式2:頁面裏面放入一個自動提交的表單,模擬一次GET請求html

  2. 方式3:頁面內部自動發起一個get方法的ajax請求前端

2.POST類型

  1. 方式1:頁面裏面放入一個自動提交的表單,模擬一次POST請求
<form action=http://wooyun.org/csrf.php method=POST>
<input type="text" name="xx" value="11" />
</form>
<script> document.forms[0].submit(); </script>
複製代碼
  1. 方式2:頁面內部自動發起一個post方法的ajax請求
  2. 方式3:頁面以GET請求發起,後臺接受到後再以POST方式轉發

四.規避攻擊的方法:

1.後端判斷referer是否合法(不推薦)

  • Referer記錄了HTTP請求的來源地址
    • 通常狀況下,受一個頁面安全限制的請求都是來源於這個網站
    • 經過HTTP的referer可知道,用戶是經過哪一個網站發送這個請求的。
// koa服務器檢查Referer示例:
app.use(async (ctx, next) => {
    let referer = ctx.headers.Referer;
    // 驗證Referer是不是以 test.example 開頭的
    if((referer != null ) && (_.startsWith(referer, "test.example")) {
        // 驗證經過
        await next();
    } else {
        驗證失敗,返回錯誤
        ctx.status = 401;
        return ctx.body = {
            err: '危險的請求,拒絕訪問'
        }
    }
}) 
複製代碼
  • 注意: Referer的判斷並非好方法,有不少缺陷,具體可見 這裏
    1. 某些瀏覽器,例如IE6FF2都是能夠本身設置Referer值的
    2. 由於Referer會記錄用戶的訪問記錄,侵犯隱私,所以在最新的瀏覽器中,用戶能夠本身設置發送請求時再也不提供Referer,這種在請求時就會被誤看成CSRF攻擊
    3. 判斷referer是否爲某域名,能夠本身來僞造
      • 例如:判斷Referer開頭是否以 126.com 以及 126 子域名,而不驗證根域名爲126.com,這裏就能夠僞造出 x.126.com.xxx.com 的域名
    4. ...

2.請求中添加上token並驗證,即校驗信息不經過cookie來實現

  1. 該作法的緣由
    • 要明白cookie得到攜帶的區別:
      • 得到cookie: 即經過js獲取cookie中的參數值,有同源策略的限制
      • 攜帶cookie: http請求時自動攜帶上cookie,會自動帶上該同源域下的全部cookie
    • token是csrf.com頁面渲染時一塊兒帶過來的,這樣的話,若是不在csrf.com頁面發起這個點贊請求,不一樣域的網站是拿不到token的
    • 而CSRF只能經過自動攜帶cookie去發起攻擊,,所以此方式可攔截
  2. 兩種具體作法
    1. 前端記錄token,在請求參數中添加token,後臺判斷:
    // 前端
        //登陸成功後,將token保存在本地(能夠是cookie方式,也能夠是 localStorage 方式)
        // 而後每次請求時添加一個 token 參數
    
    // 後端,每一個請求過來都驗證token是否有效:
    app.use( async (ctx, next) => {
        var token = req.session.token;
        var csrfToken = req.param.csrftoken;
        if(token != null && xhrToken != null && token.equals(xhrToken)) {
            // success
            await next();
        } else {
            // error
            return error
        }
    })
    複製代碼
    1. 前端記錄token,在請求頭中添加自定義頭,存放token,後臺判斷:
    // expressJwt是express框架中可用的JWT校驗插件
    var expressJwt = require('express-jwt');
    var validateJwt = expressJwt({ secret: config.secrets.session });
    app.use( async (ctx, next) => {
        // 也一樣容許校驗 token 在請求參數中的
        if(req.query && req.query.hasOwnProperty('access_token')) {
            req.headers.authorization = 'Bearer' + req.query.access_token;
        }
        // 下面會校驗請求頭中的 authorization 頭
        validateJwt(ctx, next);
    })
    複製代碼

五.注意和總結:

  1. CSRF攻擊針對的是以cookie機制來驗證登陸權限的接口
  2. CSRF攻擊不只能夠攻擊get類型的接口,也能夠攻擊其餘方法類型的接口
  3. CSRF攻擊的對象,無論有沒有開放同源接口訪問限制,由於能夠經過表單的方式發起請求,無視跨域限制
  4. 解決CSRF攻擊最有效的方法就是在請求中攜帶token到後臺去驗證
    • 能夠在請求參數中攜帶
    • 能夠在請求頭中攜帶
相關文章
相關標籤/搜索