1

我正在寻找一种方法来确保CSRF-Protection在我的Quickform2.

我找到了这个链接,但它是用于QuickForm1.

有什么想法可以适应QF2吗?

谢谢,

罗恩

4

1 回答 1

0

经过一番摆弄,我想出了这个解决方案。

也许它也可以帮助其他人:

<?php

/**
 * @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
 * Based on: http://www.zapoyok.info/2010/07/17/csrf-et-quickform-de-pear/
 */
require_once "QuickForm2.php";

class HTML_QuickForm2s extends HTML_QuickForm2
{
    /**
     * @property string $_sessionTokenKey The name of the session variable containing the token
     */
    private $_sessionTokenKey;

    /**
     * @method __construct
     * @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 $id
     * @param string $method
     * @param mixed $attributes
     * @param boolean $trackSubmit
     */
    public function __construct($id, $method = 'post', $attributes = null, $trackSubmit = true)
    {
        $this->_sessionTokenKey = "QuickForm2s_" . md5($id);

        parent::__construct($id, $method, $attributes, $trackSubmit);

        //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");

        $qfsCsrf= $this->getElementsByName('qfS_csrf');
        $qfsCsrf[0]->setValue($_SESSION[$this->_sessionTokenKey]);
    }

    /**
     * @method validate
     * @desc Check if the passed token matches the session before allowing validation
     * @return boolean
     */
    public function validate()
    {
        $submitValues = $this->getValue();

        //The token was not passed or does not match
        if (!isset($submitValues['qfS_csrf']) || $submitValues['qfS_csrf'] != $_SESSION[$this->_sessionTokenKey]) {
            $this->setError("Anti-CSRF token does not match");
        }

        return parent::validate();
    }

}
于 2015-05-12T10:01:35.300 回答