CSRF攻擊防御

CSRF 攻擊的應對之道
web安全之token和CSRF攻擊
CSRF Token 的設(shè)計是否有其必要性滤否?

CSRF 背景與介紹

CSRF(Cross Site Request Forgery, 跨站域請求偽造)是一種網(wǎng)絡(luò)的攻擊方式,它在 2007 年曾被列為互聯(lián)網(wǎng) 20 大安全隱患之一钳枕。其他安全隱患缴渊,比如 SQL 腳本注入珍逸,跨站域腳本攻擊等在近年來已經(jīng)逐漸為眾人熟知模狭,很多網(wǎng)站也都針對他們進行了防御。然而卿啡,對于大多數(shù)人來說昔瞧,CSRF 卻依然是一個陌生的概念指蚁。即便是大名鼎鼎的 Gmail, 在 2007 年底也存在著 CSRF 漏洞,從而被黑客攻擊而使 Gmail 的用戶造成巨大的損失自晰。

CSRF 攻擊實例

CSRF 攻擊可以在受害者毫不知情的情況下以受害者名義偽造請求發(fā)送給受攻擊站點凝化,從而在并未授權(quán)的情況下執(zhí)行在權(quán)限保護之下的操作。比如說酬荞,受害者 Bob 在銀行有一筆存款搓劫,通過對銀行的網(wǎng)站發(fā)送請求 http://bank.example/withdraw?account=bob&amount=1000000&for=bob2 可以使 Bob 把 1000000 的存款轉(zhuǎn)到 bob2 的賬號下。通常情況下混巧,該請求發(fā)送到網(wǎng)站后枪向,服務(wù)器會先驗證該請求是否來自一個合法的 session,并且該 session 的用戶 Bob 已經(jīng)成功登陸咧党。黑客 Mallory 自己在該銀行也有賬戶遣疯,他知道上文中的 URL 可以把錢進行轉(zhuǎn)帳操作。Mallory 可以自己發(fā)送一個請求給銀行:http://bank.example/withdraw?account=bob&amount=1000000&for=Mallory凿傅。但是這個請求來自 Mallory 而非 Bob缠犀,他不能通過安全認證,因此該請求不會起作用聪舒。這時辨液,Mallory 想到使用 CSRF 的攻擊方式,他先自己做一個網(wǎng)站箱残,在網(wǎng)站中放入如下代碼: src=”http://bank.example/withdraw?account=bob&amount=1000000&for=Mallory ”滔迈,并且通過廣告等誘使 Bob 來訪問他的網(wǎng)站。當 Bob 訪問該網(wǎng)站時被辑,上述 url 就會從 Bob 的瀏覽器發(fā)向銀行燎悍,而這個請求會附帶 Bob 瀏覽器中的 cookie 一起發(fā)向銀行服務(wù)器。大多數(shù)情況下盼理,該請求會失敗谈山,因為他要求 Bob 的認證信息。但是宏怔,如果 Bob 當時恰巧剛訪問他的銀行后不久奏路,他的瀏覽器與銀行網(wǎng)站之間的 session 尚未過期畴椰,瀏覽器的 cookie 之中含有 Bob 的認證信息。這時鸽粉,悲劇發(fā)生了斜脂,這個 url 請求就會得到響應,錢將從 Bob 的賬號轉(zhuǎn)移到 Mallory 的賬號触机,而 Bob 當時毫不知情帚戳。等以后 Bob 發(fā)現(xiàn)賬戶錢少了,即使他去銀行查詢?nèi)罩纠苁祝仓荒馨l(fā)現(xiàn)確實有一個來自于他本人的合法請求轉(zhuǎn)移了資金片任,沒有任何被攻擊的痕跡。而 Mallory 則可以拿到錢后逍遙法外椒舵。

CSRF 攻擊的對象

在討論如何抵御 CSRF 之前,先要明確 CSRF 攻擊的對象约谈,也就是要保護的對象笔宿。從以上的例子可知,CSRF 攻擊是黑客借助受害者的 cookie 騙取服務(wù)器的信任棱诱,但是黑客并不能拿到 cookie泼橘,也看不到 cookie 的內(nèi)容。另外迈勋,對于服務(wù)器返回的結(jié)果炬灭,由于瀏覽器同源策略的限制,黑客也無法進行解析靡菇。因此重归,黑客無法從返回的結(jié)果中得到任何東西,他所能做的就是給服務(wù)器發(fā)送請求厦凤,以執(zhí)行請求中所描述的命令鼻吮,在服務(wù)器端直接改變數(shù)據(jù)的值,而非竊取服務(wù)器中的數(shù)據(jù)较鼓。所以椎木,我們要保護的對象是那些可以直接產(chǎn)生數(shù)據(jù)改變的服務(wù),而對于讀取數(shù)據(jù)的服務(wù)博烂,則不需要進行 CSRF 的保護香椎。比如銀行系統(tǒng)中轉(zhuǎn)賬的請求會直接改變賬戶的金額,會遭到 CSRF 攻擊禽篱,需要保護畜伐。而查詢余額是對金額的讀取操作,不會改變數(shù)據(jù)躺率,CSRF 攻擊無法解析服務(wù)器返回的結(jié)果烤礁,無需保護讼积。

當前防御 CSRF 的幾種策略

目前業(yè)界應對 CSRF 攻擊有一些克制方法,但是每種方法都有利弊脚仔,沒有一種方法是完美的勤众。如何選擇合適的方法非常重要。如果網(wǎng)站是一個現(xiàn)有系統(tǒng)鲤脏,想要在最短時間內(nèi)獲得一定程度的 CSRF 的保護们颜,那么驗證 Referer 的方法是最方便的,要想增加安全性的話猎醇,可以選擇不支持低版本瀏覽器窥突,畢竟就目前來說,IE7+, FF3+ 這類高版本瀏覽器的 Referer 值還無法被篡改硫嘶。

  • 驗證 HTTP Referer 字段
  • 在 HTTP 頭中自定義屬性并驗證
  • 在請求地址中添加 token 并驗證

CSRF 攻擊之所以能夠成功阻问,是因為黑客可以完全偽造用戶的請求,該請求中所有的用戶驗證信息都是存在于 cookie 中沦疾,因此黑客可以在不知道這些驗證信息的情況下直接利用用戶自己的 cookie 來通過安全驗證称近。要抵御 CSRF,關(guān)鍵在于在請求中放入黑客所不能偽造的信息哮塞,并且該信息不存在于 cookie 之中刨秆。

可以在 HTTP 請求中以參數(shù)的形式加入一個隨機產(chǎn)生的 token,并在服務(wù)器端建立一個攔截器來驗證這個 token忆畅,如果請求中沒有 token 或者 token 內(nèi)容不正確衡未,則認為可能是 CSRF 攻擊而拒絕該請求。

這種方法要比檢查 Referer 要安全一些家凯,token 可以在用戶登陸后產(chǎn)生并放于 session 之中缓醋,然后在每次請求時把 token 從 session 中拿出,與請求中的 token 進行比對绊诲,但這種方法的難點在于如何把 token 以參數(shù)的形式加入請求改衩。對于 GET 請求,token 將附在請求地址之后驯镊,這樣 URL 就變成 http://url?csrftoken=tokenvalue葫督。 而對于 POST 請求來說,要在 form 的最后加上 <input type=”hidden” name=”csrftoken” value=”tokenvalue”/>板惑,這樣就把 token 以參數(shù)的形式加入請求了橄镜。但是,在一個網(wǎng)站中冯乘,可以接受請求的地方非常多洽胶,要對于每一個請求都加上 token 是很麻煩的,并且很容易漏掉,通常使用的方法就是在每次頁面加載時姊氓,使用 javascript 遍歷整個 dom 樹丐怯,對于 dom 中所有的 a 和 form 標簽后加入 token。這樣可以解決大部分的請求翔横,但是對于在頁面加載之后動態(tài)生成的 html 代碼读跷,這種方法就沒有作用,還需要程序員在編碼時手動添加 token禾唁。

該方法還有一個缺點是難以保證 token 本身的安全效览。特別是在一些論壇之類支持用戶自己發(fā)表內(nèi)容的網(wǎng)站,黑客可以在上面發(fā)布自己個人網(wǎng)站的地址荡短。由于系統(tǒng)也會在這個地址后面加上 token丐枉,黑客可以在自己的網(wǎng)站上得到這個 token,并馬上就可以發(fā)動 CSRF 攻擊掘托。為了避免這一點瘦锹,系統(tǒng)可以在添加 token 的時候增加一個判斷,如果這個鏈接是鏈到自己本站的闪盔,就在后面添加 token弯院,如果是通向外網(wǎng)則不加。不過锭沟,即使這個 csrftoken 不以參數(shù)的形式附加在請求之中抽兆,黑客的網(wǎng)站也同樣可以通過 Referer 來得到這個 token 值以發(fā)動 CSRF 攻擊识补。這也是一些用戶喜歡手動關(guān)閉瀏覽器 Referer 功能的原因族淮。

實例1:token通過請求參數(shù)或者http頭傳遞,服務(wù)端緩存在session中

HttpServletRequest req = (HttpServletRequest)request;
HttpSession s = req.getSession();

// 從 session 中得到 csrftoken 屬性
String sToken = (String)s.getAttribute(“csrftoken”); 
if(sToken == null){

    // 產(chǎn)生新的 token 放入 session 中
    sToken = generateToken();
    s.setAttribute(“csrftoken”,sToken);
    chain.doFilter(request, response);
} else {

    // 從 HTTP 頭中取得 csrftoken 
    String xhrToken = req.getHeader(“csrftoken”);

    // 從請求參數(shù)中取得 csrftoken 
    String pToken = req.getParameter(“csrftoken”);
    if(sToken != null && xhrToken != null && sToken.equals(xhrToken)){
        chain.doFilter(request, response);
    }else if(sToken != null && pToken != null && sToken.equals(pToken)){
        chain.doFilter(request, response);
    }else{
        request.getRequestDispatcher(“error.jsp”).forward(request,response);
    }
}

實例2:token通過請求參數(shù)傳遞凭涂,緩存在cookie中(適用于不允許使用session的系統(tǒng))

/**
 * 驗證防止csrf攻擊cookie值csrfToken
 * 
 * @param request 請求request
 * @param paramName token參數(shù)名
 * @param cookieName cookie名
 * @return
 */
public static boolean verifyCsrfToken(HttpServletRequest request, String paramName, String cookieName) {
    boolean result = false;
    String csrfToken = request.getParameter(paramName);
    Cookie cookies[] = request.getCookies();
    if (csrfToken != null && cookies != null) {
        for (Cookie cookie : cookies) {
            if (StringUtils.equals(cookieName, cookie.getName())) {
                result = StringUtils.equals(csrfToken, cookie.getValue());
                break;
            }
        }
    }
    return result;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末祝辣,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子切油,更是在濱河造成了極大的恐慌蝙斜,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件澎胡,死亡現(xiàn)場離奇詭異孕荠,居然都是意外死亡,警方通過查閱死者的電腦和手機攻谁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進店門稚伍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人戚宦,你說我怎么就攤上這事个曙。” “怎么了受楼?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵垦搬,是天一觀的道長呼寸。 經(jīng)常有香客問我,道長猴贰,這世上最難降的妖魔是什么对雪? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮糟趾,結(jié)果婚禮上慌植,老公的妹妹穿的比我還像新娘。我一直安慰自己义郑,他們只是感情好蝶柿,可當我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著非驮,像睡著了一般交汤。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上劫笙,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天芙扎,我揣著相機與錄音,去河邊找鬼填大。 笑死戒洼,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的允华。 我是一名探鬼主播圈浇,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼靴寂!你這毒婦竟也來了磷蜀?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤百炬,失蹤者是張志新(化名)和其女友劉穎褐隆,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體剖踊,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡庶弃,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了德澈。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片歇攻。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖圃验,靈堂內(nèi)的尸體忽然破棺而出掉伏,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布斧散,位于F島的核電站供常,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏鸡捐。R本人自食惡果不足惜栈暇,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望箍镜。 院中可真熱鬧源祈,春花似錦、人聲如沸色迂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽歇僧。三九已至图张,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間诈悍,已是汗流浹背祸轮。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留侥钳,地道東北人适袜。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像舷夺,于是被迫代替她去往敵國和親苦酱。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,781評論 2 354

推薦閱讀更多精彩內(nèi)容

  • http://www.91ri.org/tag/fuzz-bug 通常情況下冕房,有三種方法被廣泛用來防御CSRF攻擊...
    jdyzm閱讀 4,173評論 0 5
  • CSRF概念:CSRF跨站點請求偽造(Cross—Site Request Forgery)躏啰,跟XSS攻擊一樣趁矾,存...
    raincoco閱讀 831評論 0 1
  • 轉(zhuǎn)載地址:http://www.phpddt.com/reprint/csrf.htmlCSRF概念:CSRF跨站...
    matianhe閱讀 982評論 0 104
  • CSRF是什么耙册? (Cross Site Request Forgery, 跨站域請求偽造)是一種網(wǎng)絡(luò)的攻擊方式,...
    謝澤閱讀 3,230評論 0 8
  • CSRF是什么毫捣? (Cross Site Request Forgery, 跨站域請求偽造)是一種網(wǎng)絡(luò)的攻擊方式详拙,...
    天青色等煙雨閱讀 42,626評論 1 33