CSRF et QuickForm de PEAR

J’utilise encore beaucoup QuickForm de PEAR pour gérer mes formulaires, une classe pour disposer automatiquement d’une « protection » contre les CSRF trouvée à l’adresse : http://shiflett.org/articles/cross-site-request-forgeries#comment-66

/**
 * @uses HTML_QuickForm
 * @desc Add automatic CSRF mitigation to all forms by incorporating a token that must be matched in the session and forcing the use of POST method
 */
require_once "QuickForm.php";
class HTML_QuickFormS extends HTML_QuickForm {
    
    /**
     * @property string $_sessionTokenKey The name of the session variable containing the token
     */
    private $_sessionTokenKey;
    
    /**
     * @method HTML_QuickFormS
     * @desc Override the method to always use post and pass it on to the parent constructor. Create a session key for the token based on the form name.
     * @param string $formName
     * @param string $method
     * @param string $action
     * @param string $target
     * @param mixed $attributes
     * @param boolean $trackSubmit
     */
    public function HTML_QuickFormS($formName='', $method='post', $action='', $target='', $attributes=null, $trackSubmit=false){
        $this----->_sessionTokenKey = "QuickFormS_".md5($formName);
        parent::HTML_QuickForm($formName, 'post', $action, $target, $attributes, $trackSubmit);
    }
    
    /**
     * @method display
     * @desc Create a token if necessary and place a hidden field in the form before displaying
     * @return void
     */
    public function display(){
        
        //A token hasn't been created so do so
        if(!isset($_SESSION[$this->_sessionTokenKey])){
            $_SESSION[$this->_sessionTokenKey] = md5(uniqid(rand(), true).session_id()); //requires the session id to be known in order to add extra difficulty to compromising
        }
        
        //Hide the token at the end of the form
        $this->addElement("hidden", "qfS_csrf", $_SESSION[$this->_sessionTokenKey]);
        parent::display();
    }
    
    /**
     * @method validate
     * @desc Check if the passed token matches the session before allowing validation
     * @return boolean
     */
    public function validate(){
        
        //The token was not passed or does not match
        if(!isset($this->_submitValues['qfS_csrf']) || $this->_submitValues['qfS_csrf']!=$_SESSION[$this->_sessionTokenKey]){
            $this->setElementError("qfS_csrf", "Anti-CSRF token does not match");
        }
                
        return parent::validate();
    }
    
}
 

1 Comment on “CSRF et QuickForm de PEAR

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

*

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.