国产精品香蕉在线观看网,亚洲欧美精品综合在线观看,亚洲不卡av一区二区无码不卡,亚洲日本精品国产第一区二区

移動(dòng)安全 安全管理 應(yīng)用案例 網(wǎng)絡(luò)威脅系統(tǒng)安全 應(yīng)用安全 數(shù)據(jù)安全 云安全
當(dāng)前位置: 主頁(yè) > 信息安全 > 系統(tǒng)安全 >

跨站要求捏造CSRF防護(hù)編制

時(shí)間:2013-08-21 23:18來(lái)源:TuZhiJiaMi企業(yè)信息安全專家 點(diǎn)擊:
CSRF(Cross-site request forgery跨站要求捏造,也被稱成為“one click attack”或session riding,凡是縮寫為CSRF或XSRF,是一種對(duì)網(wǎng)站的歹意操縱。 1、CSRF報(bào)復(fù)打擊道理 CSRF報(bào)復(fù)打擊道理比較簡(jiǎn)單,如圖1所示
Tags系統(tǒng)安全(735)防護(hù)方法(2)CSRF(8)跨站請(qǐng)求(1)  

  CSRF(Cross-site request forgery跨站要求捏造,也被稱成為“one click attack”或session riding,凡是縮寫為CSRF或XSRF,是一種對(duì)網(wǎng)站的歹意操縱。

  1、CSRF報(bào)復(fù)打擊道理

  CSRF報(bào)復(fù)打擊道理比較簡(jiǎn)單,如圖1所示。此中Web A為存在CSRF縫隙的網(wǎng)站,Web B為報(bào)復(fù)打擊者構(gòu)建的歹意網(wǎng)站,User C為Web A網(wǎng)站的合法用戶。

跨站要求捏造CSRF防護(hù)編制

  圖1 CSRF報(bào)復(fù)打擊道理

  1. 用戶C打開瀏覽器,拜候受信賴網(wǎng)站A,輸進(jìn)用戶名和暗碼要求登錄網(wǎng)站A;

  2.在用戶信息經(jīng)由過程驗(yàn)證后,網(wǎng)站A產(chǎn)生Cookie信息并返回給瀏覽器,此時(shí)用戶登錄網(wǎng)站A成功,可以正常發(fā)送要求到網(wǎng)站A;

  3. 用戶未退出網(wǎng)站A之前,在統(tǒng)一瀏覽器中,打開一個(gè)TAB頁(yè)拜候網(wǎng)站B;

  4. 網(wǎng)站B領(lǐng)遭到用戶要求后,返回一些報(bào)復(fù)打擊性代碼,并發(fā)出一個(gè)要求要求拜候第三方站點(diǎn)A;

  5. 瀏覽器在領(lǐng)遭到這些報(bào)復(fù)打擊性代碼后,按照網(wǎng)站B的要求,在用戶不知情的環(huán)境下攜帶Cookie信息,向網(wǎng)站A發(fā)出要求。網(wǎng)站A其實(shí)不知道該要求其實(shí)是由B倡議的,所以會(huì)按照用戶C的Cookie信息以C的權(quán)限措置該要求,導(dǎo)致來(lái)自網(wǎng)站B的歹意代碼被履行。

  2、CSRF縫隙防御

  CSRF縫隙防御首要可以從三個(gè)層面進(jìn)行,即辦事端的防御、用戶端的防御和安然設(shè)備的防御。

  1、 辦事端的防御

  .1.1 驗(yàn)證HTTP Referer字段

  按照HTTP和談,在HTTP頭中有一個(gè)字段叫Referer,它記實(shí)了該HTTP要求的來(lái)歷地址。在凡是環(huán)境下,拜候一個(gè)安然受限頁(yè)面的要求必需來(lái)自于統(tǒng)一個(gè)網(wǎng)站。好比某銀行的轉(zhuǎn)賬是經(jīng)由過程用戶拜候http://bank.test/test?page=10&userID=101&money=10000頁(yè)面完成,用戶必需先登錄bank.test,然后經(jīng)由過程點(diǎn)擊頁(yè)面上的按鈕來(lái)觸發(fā)轉(zhuǎn)賬事務(wù)。當(dāng)用戶提交要求時(shí),該轉(zhuǎn)賬要求的Referer值就會(huì)是轉(zhuǎn)賬按鈕地點(diǎn)頁(yè)面的URL(本例中,凡是是以bank. test域名開首的地址)。而假定報(bào)復(fù)打擊者要對(duì)銀行網(wǎng)站實(shí)施CSRF報(bào)復(fù)打擊,他只能在本身的網(wǎng)站機(jī)關(guān)要求,當(dāng)用戶經(jīng)由過程報(bào)復(fù)打擊者的網(wǎng)站發(fā)送要求到銀行時(shí),該要求的Referer是指向報(bào)復(fù)打擊者的網(wǎng)站。是以,要防御CSRF報(bào)復(fù)打擊,銀行網(wǎng)站只需要對(duì)每個(gè)轉(zhuǎn)賬要求驗(yàn)證其Referer值,假定是以bank. test開首的域名,則申明該要求是來(lái)自銀行網(wǎng)站本身的要求,是合法的。假定Referer是其他網(wǎng)站的話,就有多是CSRF報(bào)復(fù)打擊,則拒盡該要求。

  1.2 在要求地址中添加token并驗(yàn)證

  CSRF報(bào)復(fù)打擊之所以可以或許成功,是因?yàn)閳?bào)復(fù)打擊者可以捏造用戶的要求,該要求中所有的用戶驗(yàn)證信息都存在于Cookie中,是以報(bào)復(fù)打擊者可以在不知道這些驗(yàn)證信息的環(huán)境下直接操縱用戶本身的Cookie來(lái)經(jīng)由過程安然驗(yàn)證。由此可知,抵抗CSRF報(bào)復(fù)打擊的關(guān)頭在于:在要求中放進(jìn)報(bào)復(fù)打擊者所不克不及捏造的信息,并且該信息不存在于Cookie當(dāng)中。鑒于此,系統(tǒng)開辟者可以在HTTP要求中以參數(shù)的情勢(shì)加進(jìn)一個(gè)隨機(jī)產(chǎn)生的token,并在辦事器端成立一個(gè)反對(duì)器來(lái)驗(yàn)證這個(gè)token,假定要求中沒有token或token內(nèi)容不準(zhǔn)確,則覺得多是CSRF報(bào)復(fù)打擊而拒盡該要求。

  1.3 在HTTP頭中自定義屬性并驗(yàn)證

  自定義屬性的編制也是利用token并進(jìn)行驗(yàn)證,和前一種編制不合的是,這里其實(shí)不是把token以參數(shù)的情勢(shì)置于HTTP要求當(dāng)中,而是把它放到HTTP頭中自定義的屬性里。經(jīng)由過程XMLHttpRequest這個(gè)類,可以一次性給所有該類要求加上csrftoken這個(gè)HTTP頭屬性,并把token值放進(jìn)此中。如許解決了前一種編制在要求中加進(jìn)token的不便,同時(shí),經(jīng)由過程這個(gè)類要求的地址不會(huì)被記實(shí)到瀏覽器的地址欄,也不消擔(dān)憂token會(huì)經(jīng)由過程Referer泄漏到其他網(wǎng)站。

  2、 其他防御編制

  1. CSRF報(bào)復(fù)打擊是有前提的,當(dāng)用戶拜候歹意鏈接時(shí),認(rèn)證的cookie仍然有效,所以當(dāng)用戶封鎖頁(yè)面時(shí)要及時(shí)斷根認(rèn)證cookie,對(duì)撐持TAB模式(新標(biāo)簽打開網(wǎng)頁(yè))的瀏覽器尤其首要。

  2. 盡可能罕用或不要用request()類變量,獲得參數(shù)指定request.form()仍是request. querystring (),如許有益于禁止CSRF縫隙報(bào)復(fù)打擊,此編制只不克不及完全防御CSRF報(bào)復(fù)打擊,只是必然程度上增加了報(bào)復(fù)打擊的難度。

  代碼示例:

  Java 代碼示例

  下文將以 Java 為例,對(duì)上述三種編制別離用代碼進(jìn)行示例。不管利用何種編制,在辦事器端的反對(duì)器必不成少,它將負(fù)責(zé)查抄到來(lái)的要求是不是合適要求,然后視成果而決定是不是繼續(xù)要求或丟棄。在 Java 中,反對(duì)器是由 Filter 來(lái)實(shí)現(xiàn)的。我們可以編寫一個(gè) Filter,并在 web.xml 中對(duì)其進(jìn)行建設(shè),使其對(duì)拜候所有需要 CSRF 呵護(hù)的資本的要求進(jìn)行反對(duì)。

  在 filter 中對(duì)要求的 Referer 驗(yàn)證代碼以下

  清單 1. 在 Filter 中驗(yàn)證 Referer// 從 HTTP 頭中獲得 Referer 值

  Stringreferer=request.getHeader("Referer");

  // 鑒定 Referer 是不是以 bank.example 開首

  if((referer!=null)&&(referer.trim().startsWith(“bank.example”))){

  chain.doFilter(request,response);

  }else{

  request.getRequestDispatcher(“error.jsp”).forward(request,response);

  }

  以上代碼先獲得 Referer 值,然掉隊(duì)行鑒定,當(dāng)其非空并以 bank.example 開首時(shí),則繼續(xù)要求,不然的話多是 CSRF 報(bào)復(fù)打擊,轉(zhuǎn)到 error.jsp 頁(yè)面。

  假定要進(jìn)一步驗(yàn)證要求中的 token 值,代碼以下

  清單 2. 在 filter 中驗(yàn)證要求中的 token

  HttpServletRequestreq =(HttpServletRequest)request;

  HttpSessions =req.getSession();

  // 從 session 中獲得 csrftoken 屬性

  StringsToken =(String)s.getAttribute(“csrftoken”);

  if(sToken ==null){

  // 產(chǎn)生新的 token 放進(jìn) session 中

  sToken =generateToken();

  s.setAttribute(“csrftoken”,sToken);

  chain.doFilter(request,response);

  }else{

  // 從 HTTP 頭中獲得 csrftoken

  StringxhrToken =req.getHeader(“csrftoken”);

  // 從要求參數(shù)中獲得 csrftoken

  StringpToken =req.getParameter(“csrftoken”);

  if(sToken !=null&&xhrToken !=null&&sToken.equals(xhrToken)){

  chain.doFilter(request,response);

  }elseif(sToken !=null&&pToken !=null&&sToken.equals(pToken)){

  chain.doFilter(request,response);

  }else{

  request.getRequestDispatcher(“error.jsp”).forward(request,response);

  }

  }

  起首鑒定 session 中有沒有 csrftoken,假定沒有,則覺得是第一次拜候,session 是新成立的,這時(shí)候生成一個(gè)新的 token,放于 session 當(dāng)中,并繼續(xù)履行要求。假定 session 中已有 csrftoken,則申明用戶已與辦事器之間成立了一個(gè)活躍的 session,這時(shí)候要看這個(gè)要求中有沒有同時(shí)附帶這個(gè) token,因?yàn)橐罂赡軄?lái)自于常規(guī)的拜候或是 XMLHttpRequest 異步拜候,我們別離測(cè)驗(yàn)測(cè)驗(yàn)從要求中獲得 csrftoken 參數(shù)和從 HTTP 頭中獲得 csrftoken 自定義屬性并與 session 中的值進(jìn)行比較,只要有一個(gè)處所帶有有效 token,就鑒定要求合法,可以繼續(xù)履行,不然就轉(zhuǎn)到弊端頁(yè)面。生成 token 有良多種編制,任何的隨機(jī)算法都可利用,Java 的 UUID 類也是一個(gè)不錯(cuò)的選擇。

  除在辦事器端操縱 filter 來(lái)驗(yàn)證 token 的值以外,我們還需要在客戶端給每個(gè)要求附加上這個(gè) token,這是操縱 js 來(lái)給 html 中的鏈接和表單要求地址附加 csrftoken 代碼,此中已定義 token 為全局變量,其值可以從 session 中獲得。

  清單 3. 在客戶端對(duì)要求附加 token

  function appendToken(){

  updateForms();

  updateTags();

  }

  function updateForms(){

  // 獲得頁(yè)面中所有的 form 元素

  var forms =document.getElementsByTagName('form');

  for(i=0;i

  下面的buy.php法度措置表單的提交信息:

  

  session_start();

  $clean =array();

  if(isset($_REQUEST['item']&&isset($_REQUEST['quantity']))

  {

  /* Filter Input ($_REQUEST['item'], $_REQUEST['quantity']) */

  if(buy_item($clean['item'],$clean['quantity']))

  {

  echo '<  session_start();

  $clean =array();

  if(isset($_REQUEST['item']&&isset($_REQUEST['quantity']))

  {

  /* Filter Input ($_REQUEST['item'], $_REQUEST['quantity']) */

  if(buy_item($clean['item'],$clean['quantity']))

  {

  echo '<  session_start();

  $clean =array();

  if(isset($_REQUEST['item']&&isset($_REQUEST['quantity']))

  {

  /* Filter Input ($_REQUEST['item'], $_REQUEST['quantity']) */

  if(buy_item($clean['item'],$clean['quantity']))

  {

  echo '

Thanks for your purchase.

';

  }

  else

  {

  echo '

There was a problem with your order.

';

  }

  }?>

  報(bào)復(fù)打擊者會(huì)起首利用這個(gè)表單來(lái)不雅察它的動(dòng)作。例如,在采辦了一支鉛筆后,報(bào)復(fù)打擊者知道了在采辦成功后會(huì)呈現(xiàn)感激信息。寄望到這一點(diǎn)后,報(bào)復(fù)打擊者會(huì)測(cè)驗(yàn)測(cè)驗(yàn)經(jīng)由過程拜候下面的URL以用GET編制提交數(shù)據(jù)是不是能達(dá)到一樣的目標(biāo):

  http://store.example.org/buy.php?item=pen&quantity=1

  假定能成功的話,報(bào)復(fù)打擊者此刻就獲得了當(dāng)合法用戶拜候時(shí),可以激發(fā)采辦的URL格局。在這類環(huán)境下,進(jìn)行跨站要求捏造報(bào)復(fù)打擊很是等閑,因?yàn)閳?bào)復(fù)打擊者只要激發(fā)受害者拜候該URL便可。

  請(qǐng)看下面對(duì)前例利用更改后的代碼:

  php

  session_start();

  $token =md5(uniqid(rand(),TRUE));

  $_SESSION['token']=$token;

  $_SESSION['token_time']=time();?>

  表單:

  

  經(jīng)由過程這些簡(jiǎn)單的點(diǎn)竄,一個(gè)跨站要求捏造報(bào)復(fù)打擊就必需包含一個(gè)合法的驗(yàn)證碼以完全仿照表單提交。因?yàn)轵?yàn)證碼的保留在用戶的session中的,報(bào)復(fù)打擊者必需對(duì)每個(gè)受害者利用不合的驗(yàn)證碼。如許就有效的限制了對(duì)一個(gè)用戶的任何報(bào)復(fù)打擊,它要求報(bào)復(fù)打擊者獲得別的一個(gè)用戶的合法驗(yàn)證碼。利用你本身的驗(yàn)證碼來(lái)捏造別的一個(gè)用戶的要求是無(wú)效的。

  該驗(yàn)證碼可以簡(jiǎn)單地經(jīng)由過程一個(gè)前提表達(dá)式來(lái)進(jìn)行查抄:

  

  if(isset($_SESSION['token'])&&$_POST['token']==$_SESSION['token'])

  {

  /* Valid Token */

  }?>  if(isset($_SESSION['token'])&&$_POST['token']==$_SESSION['token'])

  {

  /* Valid Token */

  }?>  if(isset($_SESSION['token'])&&$_POST['token']==$_SESSION['token'])

  {

  /* Valid Token */

  }?>

  你還能對(duì)驗(yàn)證碼加上一個(gè)有效時(shí)候限制,如5分鐘:

  

  $token_age =time()-$_SESSION['token_time'];

  if($token_age <  $token_age =time()-$_SESSION['token_time'];

  if($token_age <  $token_age =time()-$_SESSION['token_time'];

  if($token_age <=300)

  {

  /* Less than five minutes has passed. */

  }?>

  經(jīng)由過程在你的表單中包含驗(yàn)證碼,你事實(shí)上已消弭跨站要求捏造報(bào)復(fù)打擊的風(fēng)險(xiǎn)??梢栽谌魏涡枰男邪殉值娜魏伪韱沃欣眠@個(gè)流程。

------分隔線----------------------------

推薦內(nèi)容