2013-10-27 8 views
3

У меня включен csrf с codeigniter, который работает правильно в FireFox и Google Chrome. Однако в IE он показывает эту ошибку в веб-разработчик сетевой инструмент панели:codeigniter csrf с ajax не работает в IE

enter image description here

и в детализированном виде:

enter image description here

мой $.post вызов:

var ctn = $.cookie('csrf_cookie'); 
$.post('some_path', { 
    'my_token': ctn 
}, function (data) { 
    if (data.res == 'something') { 
     //process here 
    }, 'json'); 

и значение ctn, которое является файлом cookie, который содержит значение токена CSRF отображается правильно, когда я console.log('ctn: '+ctn), как я получаю:

ctn: 78346b5d0ec105efcce796f93ecc3cbb 

Любая помощь или предложение отлаживать больше будет весьма признателен.

P.S .: У меня есть vhost, и я действительно не знаю, имеет ли это значение IE.

Update:

Я читал о проблемах с CSRF в IE некоторые предложили использовать заголовки P3P, поэтому я добавил этот заголовок на индексную страницу:

header('P3P:CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT'); 

Но еще есть такая же проблема ,

Любые другие предложения?

+0

Вы пробовали настройки CONTENTTYPE: '' "приложения/JSON" '' для запроса? На стороне: я столкнулся с множеством проблем, которые все пришли из кеширования IE ajax-запросов ... – moritzpflaum

+0

Я уже пробовал это. Не работает –

+0

BTW, IE улавливает запрос, но он возвращает 500 из-за того, что csrf не проверяется. –

ответ

3

Как я предлагаю в my article. Лучше использовать сообщение в net.tutsplus с заголовком: Protect a CodeIgniter Application Against CSRF. Это старый пост, и решение для Codeignter 1.7.x. Однако это единственное правильное решение для Codeigniter 2, которое я смог найти до сих пор, чтобы обеспечить защиту CSRF в Codeigniter. Основная проблема, которую мы имеем здесь, заключается в том, что Codeigniter использует COOKIE. Однако этот пост использует сеанс Codeigniter, который более безопасен для использования, и он работает для всех браузеров без каких-либо проблем. Статья net.tutsplus будет работать для запроса AJAX и без AJAX.

Так что мое предложение заключается в том, если вы не можете найти работу вокруг вашего вопроса, вы можете попытаться реализовать статью: Protect a CodeIgniter Application Against CSRF

+0

так каким образом вы реализовали с продуктовым сыром. Поскольку GC работает в IE с реализованным csrf. –

+0

В продуктовом CRUD У меня есть простая реализация защиты csrf с установкой по умолчанию Codeigniter и она не работает для всех IE! Однако это не ошибка продуктового CRUD, это ошибка Codeigniter, поэтому я не могу заставить пользователей взломать Codeigniter, чтобы заставить его работать. Вот почему я нашел время и написал статью о «5 причинах НЕ использовать csrf_protection в Codeigniter». Некоторым понравилась статья, но некоторые люди ее ненавидят. Я знаю, что ответ - это не тот ответ, который вы хотели услышать, но это мое мнение после нескольких дней с защитой csrf :) –

+1

+ 1, john - Я вас уважаю. Таким образом, я уважаю ваше мнение. в IE9 + IE10, он отлично работает, и поэтому я спросил вас, чтобы у меня была возможность применить этот же метод в моем коде. в любом случае, спасибо за ваш ответ, и сейчас я оставлю свой вопрос открытым, чтобы посмотреть, добавит ли кто-нибудь еще его. –

2

Благодаря @John с предложением осуществить CSRF сам, Я прошел первый выпуск. Однако оказалось, что IE вообще не отправляет данные сообщения (после отладки). Итак, возникает вопрос о stackoverflow с заголовком IE is refusing to send data through $.ajax , и для решения этой проблемы вам нужно добавить этот тег meta, чтобы сообщить IE работать с javascript в режиме совместимости с IE9.

<meta http-equiv="x-ua-compatible" content="IE=9" > 

Теперь за статью об использовании крюков, чтобы обойти CSRF, он пропускает один вопрос, который, если вы используете .serializeArray() или любой эквивалент в JQuery, чтобы отправить форму, вы должны изменить
validate_tokens функцию для проверки token_name внутри размещенной массива.

Надежда это сэкономит кому-то с той же проблемой

Примечание: добавление мета-тег без перезаписи CSRF не решит проблему.

Update 1:

Вот реализация Я использую:

<?php 
/** 
* Description of csrf_protection 
* @author Ian Murray 
*/ 
class Csrf_Protection { 

    private $CI; 
    private static $token_name = 'somename'; 
    private static $token; 

    public function __construct() { 
     $this->CI = &get_instance(); 
    } 

/** 
* Generates a CSRF token and stores it on session. Only one token per session is generated. 
* This must be tied to a post-controller hook, and before the hook 
* that calls the inject_tokens method(). 
* 
* @return void 
* @author Ian Murray 
*/ 
    public function generate_token() 
    { 
      // Load session library if not loaded 
      $this->CI->load->library('session'); 

      if ($this->CI->session->userdata(self::$token_name) === FALSE) 
      { 
      // Generate a token and store it on session, since old one appears to have expired. 
      self::$token = md5(uniqid() . microtime() . rand()); 

      $this->CI->session->set_userdata(self::$token_name, self::$token); 
      } 
      else 
      { 
      // Set it to local variable for easy access 
      self::$token = $this->CI->session->userdata(self::$token_name); 
      } 
    } 

    /** 
    * Validates a submitted token when POST request is made. 
    * 
    * @return void 
    * @author Ian Murray 
    */ 
    public function validate_tokens() 
    { 
    // Is this a post request? 
    if ($_SERVER['REQUEST_METHOD'] == 'POST') 
    { 
     // Is the token field set and valid? 
     $posted_token = $this->CI->input->post(self::$token_name); 
     if($posted_token === FALSE){ 
      $posted_token = $this->_get_token_in_post_array($this->CI->input->post()); 
      $this->_check_all_post_array($posted_token); 
     } 
    } 
    } 
    /** 
    *takes the posted token and check it after multidimesional-array search 
    *@params $posted_token 
    *@author Mamdouh Alramadan 
    */ 
    private function _check_all_post_array($posted_token) 
    { 
     if ($posted_token === 'error' || $posted_token != $this->CI->session->userdata(self::$token_name)) 
     { 
     // Invalid request, send error 400. 
     show_error('Request was invalid. Tokens did not match.', 400); 
     } 
    } 


    /** 
    * This injects hidden tags on all POST forms with the csrf token. 
    * Also injects meta headers in <head> of output (if exists) for easy access 
    * from JS frameworks. 
    * 
    * @return void 
    * @author Ian Murray 
    */ 
    public function inject_tokens() 
    { 
    $output = $this->CI->output->get_output(); 

    // Inject into form 
    $output = preg_replace('/(<(form|FORM)[^>]*(method|METHOD)="(post|POST)"[^>]*>)/', 
          '$0<input type="hidden" name="' . self::$token_name . '" value="' . self::$token . '">', 
          $output); 

    // Inject into <head> 
    $output = preg_replace('/(<\/head>)/', 
          '<meta name="cname" content="' . self::$token_name . '">' . "\n" . '<meta name="cval" content="' . self::$token . '">' . "\n" . '$0', 
          $output); 

    $this->CI->output->_display($output); 
    } 


/** 
* takes the posted array and check for the token inside it 
* @params $arr array 
* @author Mamdouh Alramadan 
*/ 
    private function _get_token_in_post_array($arr) 
    {//this function is customized to my case but it's easy to adapt 
     if(is_array($arr)){ 
     $key = $this->_recursive_post_array_search(self::$token_name, $arr);//this will return data if token found 
     if($key === 'data'){//I'm expecting the token inside data array 
      $key = $this->_recursive_post_array_search(self::$token_name, $arr['data']); 
      return isset($arr['data'][$key]['value'])?$arr['data'][$key]['value']:FALSE; 
     } 
     } 
     return 'error'; 
    } 
    //some custom function to do multi-dimensional array search, can be replaced with any other searching function. 
    private function _recursive_post_array_search($needle,$haystack) { 
     foreach($haystack as $key=>$value) { 
      $current_key=$key; 
      if($needle===$value OR (is_array($value) && $this->_recursive_post_array_search($needle,$value) !== false)) { 
       return $current_key; 
      } 
     } 
     return false; 
    } 

} 

?> 
Смежные вопросы