2012-01-05 23 views
1

私はバックエンドでcodeigniterを使用しています。Codeigniter AJAX CSRF protection

最近、私は「CSRF」という言葉を聞いて、要求を守ることに決めました。

はほとんど自分のサイト上のすべてのアクションが[私はビューファイルにCSRFトークンを注入する方法を、ここで疑問?]アヤックス&を通じて、私はDOM操作を使用して/追加ページのコンテンツを作成していますいくつかの倍である

Okkey、その後、どうすればそれを検証できますか?

これらの値をトークンとして追加し、サーバーに渡したとしたら、コンストラクタを使用して&がこれを検証できるとしますか?

例:

Class Cl_Controller extends Ci_controller 
{ 
    function __construct() 
{ 
    //loading libraries,models,helpers etc... 

    if (isset($this->input->get_post("CSRF_TOKEN")) || _another_condition_) 
    { 
     // The CSRF TOKEN is invalid or null ,the action cannot be done... 
    } 
} 
function register() 
{ 
    //some codes... 
} 
function delete_user() 
{ 
    //some codes 
} 
} 

は、それはいくつかのことリンクこれを行うことは可能ですか?

良いアイデアを提案してください。&通常の方法です。

ありがとうございます。

+0

[CSRF対策](http://en.wikipedia.org/wiki/Cross-site_request_forgery#Prevention) – hakre

+0

[AjaxでCodeIgniterのCSRF保護](http://ericlbarnes.com/post/10728867961/ codeigniter-csrf-protection-with-ajax)が役に立ちます。 – Mudshark

答えて

3

私のajax呼び出しでは、通常2つのチェックを行います。

小さなヘルパーファイルを使用して、それがajaxリクエストであることを確認してください。

<?php if (! defined('BASEPATH')) exit('No direct script access allowed'); 

if (! function_exists('ajax_check')) { 
    /** 
    * Check AJAX 
    * 
    * Checks to see if you (or the royal I) are dealing with an AJAX call. 
    * 
    * @return boolean 
    */ 
    function ajax_check() { 
     if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') { 
      return TRUE; 
     } else { 
      show_404(); 
      return FALSE; 
     } 
    } 
} 

if (! function_exists('ajax_response')) { 
    /** 
    * JSON Response Wrapper 
    * 
    * Wraps up any data nicely for sending back to an ajax call 
    * 
    * @return string 
    */ 
    function ajax_response($status, $data) { 
     if (!is_array($data)) { 
      $data = array(); 
     } 
     // Set the JSON header appropriately 
     header('Content-Type: application/json'); 
     // Echo out the array into json 
     echo json_encode(array_merge(array('status' => $status), $data)); 
     exit; 
    } 
} 

if (! function_exists('ajax_force_fail')) { 
    /** 
    * Force AJAX Failure 
    * 
    * If you ever need to, force an AJAX to fail 
    */ 
    function ajax_force_fail() { 
     $_ci =& get_instance(); 
     $_ci->output->set_status_header(500); 
    } 
} 

です。

public function some_function() { 
    $this->load->helper('ajax'); 
    ajax_check(); 

    try { 
     // do something 
     ajax_response('success', array('data' => $some_var)); 
    } catch (Exception $e) { 
     ajax_response('failure', array('data' => $e->getMessage())); 
    } 
} 

同様のアプローチのxsrf。 ファイル:

<?php if (! defined('BASEPATH')) exit('No direct script access allowed'); 

if (! function_exists('xsrf_get_token')) { 
    /** 
    * Get XSRF Token 
    * 
    * Returns a token that exists for one request that verifies that 
    * the action was executed by the person that requested it 
    * 
    * @return string 
    */ 
    function xsrf_get_token() { 
     $ci =& get_instance(); 
     if ($ci->session->userdata('xsrf_hash')) { 
      $token = $ci->session->userdata('xsrf_hash'); 
     } else { 
      // Generate the token 
      $token = sha1(microtime().$ci->uri->uri_string()); 
      // Set it in the session 
      $ci->session->set_userdata('xsrf_hash', $token); 
     } 

     //Return it 
     return $token; 
    } 
} 

if (! function_exists('xsrf_get_token_field')) { 
    /** 
    * Get XSRF Token Field 
    * 
    * Returns an xhtml form element to include xsrf token. 
    * You can specify the id/name attribute of the input. 
    * Has a dependancy to get_xsrf_token(). 
    * 
    * @param string The id/name to be used 
    * @return string 
    */ 
    function xsrf_get_token_field($name='auth_token') { 
     return '<input type="hidden" id="'.$name.'" name="'.$name.'" value="' .xsrf_get_token(). '" />'; 
    } 
} 

if (! function_exists('xsrf_delete_token')) { 
    /** 
    * Delete XSRF Token 
    * 
    * Deletes the xsrf token 
    * 
    * @return boolean 
    */ 
    function xsrf_delete_token() { 
     $ci =& get_instance(); 
     if ($ci->session->userdata('xsrf_hash')) { 
      $ci->session->unset_userdata('xsrf_hash'); 
      return TRUE; 
     } else { 
      return FALSE; 
     } 
    } 
} 

if (! function_exists('xsrf_check_token')) { 
    /** 
    * Get XSRF Token Field 
    * 
    * Checks that the token is still valid, returns true if so. 
    * Deletes old token after valid or fail. 
    * Has a dependacy to xsrf_delete_token() 
    * 
    * @param string The challenge token 
    * @return boolean 
    */ 
    function xsrf_check_token($challenge_token) { 
     // CI 
     $ci =& get_instance(); 
     // Get the stored token 
     $token = $ci->session->userdata('xsrf_hash'); 
     // Delete the old token 
     xsrf_delete_token(); 
     // Returns if the token is the right token 
     return ($token == $challenge_token); 
    } 
} 

使用(制御装置)

public function some_other_function() { 
    $this->form_validation->set_rules('username', 'Username', 'required|callback_check_token'); 
    if($this->form_validation->run() == TRUE) { 
     // do something 
    } else { 
     // something else 
    } 
} 

// callback function 
public function check_token($val) { 
    if (xsrf_check_token($val) == TRUE) { 
     return TRUE; 
    } else { 
     $this->form_validation->set_message('check_token', 'Oops'); 
     return FALSE; 
    } 
} 

<form action="" method="post"> 
    <?php echo xsrf_get_token_field(); ?> 
    ... 
</form> 
+0

ビューでは、xsrf_get_token_field()をエコーする必要があります。これはhtmlを返し、直接エコーしません。 – manavo

+0

私の悪い、答えを変更しました。 – Rooneyl

+0

これは良いですが、Javaスクリプト(いくつかの部分)によって生成されたため、私はビューファイルでphpコードを直接使うことはできません。 – Red