2009-10-26 13 views
1

Mon programme utilise Zend Framework, et je voulais protéger les utilisateurs de CSRF en utilisant Zend_Form_Element_Hash. Mais cela ne semble pas fonctionner.Comment puis-je protéger les utilisateurs contre les contrefaçons de requêtes inter-sites à l'aide de Zend Framework?

Par exemple, mon code pour le formulaire est Logout

$exithash = new Zend_Form_Element_Hash('hihacker', array('salt' => 'exitsalt')); 
    $this->addElement($exithash); 

Dans mon plugin Auth pour contrôleur je

$exitForm = new R00_Form_Exit(); 

    if ($exitForm->isValid($_POST)) { 
     R00_Auth::logout(); // a wrapper for Zend_Auth::getInstance()->clearIdentity(); 

     Zend_Registry::get('Log')->info('User has logged out'); 

     $this->setRedirect($request); // redirect to the current page 
    } 

Et dans ma mise en page

echo new R00_Form_Exit(); 

D'accord. Mais ça ne marche pas, je clique sur le bouton submit du formulaire, la page se recharge mais l'identité existe toujours. Comme je me suis rendu compte, Zend_Form_Element_Hash génère une nouvelle valeur de hachage pour chaque formulaire de temps crée et compare le hachage de l'utilisateur avec le hachage de la session - le dernier hachage généré! C'est très étrange. Même si j'essaie, par exemple, de créer un seul R00_Form_Exit dans mon application, de le stocker dans Registry et d'en faire un écho, ouvrir une page de mon site "dans un nouvel onglet" empêchera tous les formulaires protégés par csrf de fonctionner.

Alors, comment puis-je protéger?

Répondre

1

Vous devriez vérifier si le Zend_Form_Element_Hash est capable de sauvegarder le hachage dans un Zend_Session_Namespace. C'est le comportement attendu selon la documentation de cet élément: Zend Documentation

+0

Comment vérifier? Je n'ai aucune idée :) Btw, j'utilise Zend_Cache avec l'adaptateur par défaut, qui utilise Zend_Session, et cela fonctionne très bien. Donc, je pense qu'il n'y a pas de problème –

+0

Essayez simplement de vider $ _SESSION, qui devrait contenir toutes les valeurs de tous les espaces de noms Zend_Session. Si quelque part est une valeur de l'élément Hash Form, vérifiez si elle reste la même pour les deux demandes. –

+0

Non, ce n'est pas le même :([ "Zend_Form_Element_Hash_exitsalt_hihacker"] [ "hash"] était "66cb145466361f62c7cf22899cc8807e" sur une page et "405a7413ff1b58ae966dbfac4a1b9f16" sur un autre –

-1

Ici je propose ma propre solution. Mais ce n'est toujours pas très cool, donc je serai heureux d'entendre d'autres meilleures solutions et commentaires à ce sujet.

Je génère un hachage pour chaque utilisateur à partir de son hash de mot de passe et d'autres paramètres. Le hachage est constant pour chaque utilisateur jusqu'à ce qu'il changer son mot de passe:

public function getSecurityHash() { 
      return md5($this->getIntID() . $this->getLogin() . 'R00SuperSalt'); 
    } 

Et, sous la forme:

$exithash = new Zend_Form_Element_Hidden('exithash'); 
    $exithash->setValue(R00_Auth::getUser()->getSecurityHash()) 
      ->addValidator('Identical', false, array(
       R00_Auth::getUser()->getSecurityHash() 
      )) 
      ->setDecorators(array('ViewHelper')) 
      ->setRequired(true); 
+0

$ exithash-> setValue (R00_Auth :: getUser() -> getSecurityHash()) -> addValidator ('Identique', faux, tableau ( R00_Auth :: getUser() -> getSecurityHash() )); Cela ne détruit-il pas complètement l'effet des hachages? Je veux dire, c'est comme if ("foo" == "foo") –

+0

Non, ce n'est pas le cas :) Le code est dans le init() de la classe. Dans le -> isValid(), toutes les entrées de l'utilisateur se remplissent en valeurs de formulaire, donc -> setValue() affecte uniquement la valeur de l'élément caché –

+1

Ceci n'est pas CSRF! Le jeton CSRF doit être différent sur une base par session (pas sûr, mais peut-être même sur demande). –

1

Il est censé être différent, chaque fois que vous appelez sur le générateur de hachage, en l'espace de noms SESSION et l'emplacement que vous avez spécifiés. C'est pourquoi vous créez uniquement un hachage lorsque vous créez le formulaire réel. Ce faisant, stocke le hachage pour un saut (ce qui signifie le chargement de la page) et l'oublie (surtout) si vous régénérez un formulaire pour un utilisateur. C'est l'objectif de CSRF! Pour empêcher le détournement de formulaire en invalidant les formulaires périmés.(essentiellement)

Si vous ne parvenez pas à « vérifier » une forme à cause du hachage changeant à chaque fois, vous effectuez la tâche dans le mauvais ordre et ont besoin de réévaluer votre processus.