Por que o codeigniter2 não armazena o csrf_hash de forma mais segura, como session?

Por que o token de proteção CSRF gerado não é salvo e usado via SESSION como sugerido aqui ? Atualmente no CI2, o mecanismo de proteção CSRF (na class Security) é tal:

1.generar um valor exclusivo para o token CSRF na function _csrf_set_hash ():

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

2. Insira esse token no campo oculto do formulário (usando o form_open helper)

3. Um usuário envia o formulário e um servidor recebe o token via POST. O CI executa a verificação de token na function “_sanitize_globals ()” na class Input:

 $this->security->csrf_verify(); 

4. A function “csrf_verify” da class de segurança apenas checa é POST [‘token’] set e POST [‘token’] igual a 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; } 

Por que não armazenar token na session? IMHO apenas verificando é POST [‘token’] não vazio e é igual a COOKIE [‘token’] não é suficiente porque ambos podem ser enviados por um site malévolo.

No CodeIgniter, eles não usam sessões nativas do PHP em qualquer lugar do código.

O exemplo fornecido é mostrado usando sessões de PHP nativas.

Ao usar a class de session CodeIgniter, há: armazenar dados via cookies ou armazená-los no database. [referência: http://codeigniter.com/user_guide/libraries/sessions.html ]

Ao verificar os dados do csrf, não faria sentido verificar o database sempre que fosse possível, seria plausível armazená-los nos cookies.

Eu acho que geralmente é seguro, mas existem algumas janelas de vulnerabilidade com esse método. Talvez a criptografia com a chave do lado do servidor possa ajudar a aumentar a segurança …

EDITAR:

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

De acordo com o artigo, diz que CSFF Protection with Session independente nonce (usado pelo CodeIgniter) tem uma vulnerabilidade ao CSRF + MITM Attack ( Man-in-the-Middle ):

O invasor pode configurar o cookie CSRF usando Set-Cookie e, em seguida, fornecer um token correspondente nos dados do formulário POST. Uma vez que o site não vincula os cookies da session aos cookies CSRF, não tem como determinar que o cookie CSRF token + é genuíno (fazer hashing etc. de um deles não funcionará, pois o atacante pode apenas obter um par válido do site diretamente, e use esse par no ataque).

Praticamente, a function csrf_verify () só verifica se o cookie e o POST de input são iguais, os quais ambos podem ser criados através de javascript simples. Você deve pensar duas vezes em usar isso se você for sério sobre segurança.

Fonte: Como esse ataque Man-In-The-Middle funciona?

Há algumas razões.

Primeiro, ser que armazenar o token no cookie não é inseguro. O Anti-CSRF não foi projetado para impedir a publicação automatizada de conteúdo, é evitar a criação de um pedido como usuário autenticado (via iframe ou um link simples). Enquanto o próprio token não for adivinhado, isso é suficiente.

O segundo sendo, se ele está armazenado na session, então você precisa de sessões habilitadas, isso também causa problemas de usabilidade porque, se sua session expirar e você tiver uma página aberta com um formulário, você não pode mais enviar esse formulário (mesmo que o próprio formulário não requer um estado logado).

Porque CSRF significa “Cross-site Request Forgery”. Um exemplo deste ataque seria se você soubesse que alguém tinha uma instalação wordpress em http://somedomain.com/wordpress . Você poderia fazê-los clicar em um novo link, o que realmente iria fazer algo ruim em seu painel de controle wordpress. CSRF foi projetado para evitar isso, verificando que a ação tomada foi destinada pelo usuário a tomar a ação.

Mesmo que alguém soubesse como forjar tanto o cookie quanto o campo de formulário oculto para coincidir, não há como fazer esse cross-site, e não há falsificação para evitar de qualquer maneira.