Почему codeigniter2 не сохраняет csrf_hash более безопасным способом, например сеансом?

Почему сгенерированный токен защиты CSRF не сохраняется и используется через SESSION, как предлагается здесь ? В настоящее время в CI2 механизм защиты CSRF (в классе безопасности) таков:

1.генерировать уникальное значение для токена CSRF в функции _csrf_set_hash ():

$this->csrf_hash = md5(uniqid(rand(), TRUE)); 

2. Вставьте этот токен в скрытое поле формы (с помощью form_open helper)

3. Пользователь отправляет форму, и сервер получает токен через POST. CI выполняет проверку маркера в функции «_sanitize_globals ()» в классе ввода:

 $this->security->csrf_verify(); 

4. Функция «csrf_verify» только для проверки класса безопасности – это POST ['токен'] и POST ['токен'] равен COOKIE ['token'];

 public function csrf_verify(){ // If no POST data exists we will set the CSRF cookie if (count($_POST) == 0) { return $this->csrf_set_cookie(); } // Do the tokens exist in both the _POST and _COOKIE arrays? if ( ! isset($_POST[$this->_csrf_token_name]) OR ! isset($_COOKIE[$this->_csrf_cookie_name])) { $this->csrf_show_error(); } // Do the tokens match? if ($_POST[$this->_csrf_token_name] != $_COOKIE[$this->_csrf_cookie_name]) { $this->csrf_show_error(); } // We kill this since we're done and we don't want to // polute the _POST array unset($_POST[$this->_csrf_token_name]); // Nothing should last forever unset($_COOKIE[$this->_csrf_cookie_name]); $this->_csrf_set_hash(); $this->csrf_set_cookie(); log_message('debug', "CSRF token verified "); return $this; } с public function csrf_verify(){ // If no POST data exists we will set the CSRF cookie if (count($_POST) == 0) { return $this->csrf_set_cookie(); } // Do the tokens exist in both the _POST and _COOKIE arrays? if ( ! isset($_POST[$this->_csrf_token_name]) OR ! isset($_COOKIE[$this->_csrf_cookie_name])) { $this->csrf_show_error(); } // Do the tokens match? if ($_POST[$this->_csrf_token_name] != $_COOKIE[$this->_csrf_cookie_name]) { $this->csrf_show_error(); } // We kill this since we're done and we don't want to // polute the _POST array unset($_POST[$this->_csrf_token_name]); // Nothing should last forever unset($_COOKIE[$this->_csrf_cookie_name]); $this->_csrf_set_hash(); $this->csrf_set_cookie(); log_message('debug', "CSRF token verified "); return $this; } с public function csrf_verify(){ // If no POST data exists we will set the CSRF cookie if (count($_POST) == 0) { return $this->csrf_set_cookie(); } // Do the tokens exist in both the _POST and _COOKIE arrays? if ( ! isset($_POST[$this->_csrf_token_name]) OR ! isset($_COOKIE[$this->_csrf_cookie_name])) { $this->csrf_show_error(); } // Do the tokens match? if ($_POST[$this->_csrf_token_name] != $_COOKIE[$this->_csrf_cookie_name]) { $this->csrf_show_error(); } // We kill this since we're done and we don't want to // polute the _POST array unset($_POST[$this->_csrf_token_name]); // Nothing should last forever unset($_COOKIE[$this->_csrf_cookie_name]); $this->_csrf_set_hash(); $this->csrf_set_cookie(); log_message('debug', "CSRF token verified "); return $this; } 

Почему бы не хранить токен в сеансе? IMHO просто проверяет POST ['токен'] непустым и равен COOKIE ['токен'] недостаточно, потому что оба могут быть отправлены злым сайтом.

В CodeIgniter они не используют собственные PHP-сессии в любом месте кода.

Представленный вами пример показан с использованием собственных PHP-сессий.

При использовании класса SessionIgniter Session есть либо: хранить данные через файлы cookie, либо хранить их в базе данных. [ссылка: http://codeigniter.com/user_guide/libraries/sessions.html ]

Проверяя данные csrf, было бы бессмысленно проверять базу данных каждый раз, было бы правдоподобно хранить их в файлах cookie.

Я думаю, что это вообще безопасно, но есть некоторые уязвимости в этом методе. Возможно, шифрование с помощью серверного ключа может помочь повысить безопасность …

РЕДАКТИРОВАТЬ:

https://code.djangoproject.com/wiki/CsrfProtection#Sessionindependentnonce

Согласно статье, в ней говорится, что защита CSRF с независимым от сеанса nonce (используется CodeIgniter) имеет уязвимость для CSRF + MITM Attack ( Man-in-the-Middle ):

Злоумышленник может установить cookie CSRF с помощью Set-Cookie, а затем предоставить соответствующий токен в данных формы POST. Поскольку сайт не связывает файлы cookie сеанса с кукисами CSRF, у него нет способа определить, что токен CSRF + cookie является подлинным (выполнение хэширования и т. Д. Одного из них не будет работать, так как злоумышленник может просто получить действительную пару с сайта напрямую, и использовать эту пару в атаке).

В значительной степени функция csrf_verify () проверяет только то, является ли cookie и POST POST равным, которые оба могут быть созданы с помощью простого javascript. Вы должны подумать дважды об использовании этого, если серьезно относитесь к безопасности.

Источник: Как работает эта атака «Человек-в-центре»?

Есть несколько причин.

Первое, что хранение токена в файле cookie небезопасно. Anti-CSRF не предназначен для предотвращения автоматической публикации контента, это означает, что он не должен подталкивать запрос как аутентифицированный пользователь (через iframe или простую ссылку). До тех пор, пока сам токен не догадается, этого достаточно.

Во-вторых, если он хранится в сеансе, тогда вам нужны сеансы, это также вызывает проблемы с удобством использования, потому что если ваш сеанс истекает, и у вас есть открытая страница с формой, вы больше не можете отправлять эту форму (даже если сама форма не требуется регистрируемое состояние).

Потому что CSRF означает «Подделка запросов на межсайтовый сайт». Примером этого нападения было бы, если бы вы знали, что кто-то установил WordPress на http://somedomain.com/wordpress . Вы можете заставить их щелкнуть по новой ссылке, которая действительно пойдет на что-то плохое на панели управления WordPress. CSRF был разработан для предотвращения этого, подтверждая, что предпринятое действие было предназначено для пользователя, предпринимающего действие.

Даже если кто-то знал, как подделывать как cookie, так и скрытое поле формы, чтобы соответствовать, нет никакого способа сделать этот кросс-сайт, и в любом случае нет подделки.