File indexing completed on 2025-03-02 05:29:25
0001 <?php 0002 /** 0003 * Zend Framework 0004 * 0005 * LICENSE 0006 * 0007 * This source file is subject to the new BSD license that is bundled 0008 * with this package in the file LICENSE.txt. 0009 * It is also available through the world-wide-web at this URL: 0010 * http://framework.zend.com/license/new-bsd 0011 * If you did not receive a copy of the license and are unable to 0012 * obtain it through the world-wide-web, please send an email 0013 * to license@zend.com so we can send you a copy immediately. 0014 * 0015 * @category Zend 0016 * @package Zend_Form 0017 * @subpackage Element 0018 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0019 * @license http://framework.zend.com/license/new-bsd New BSD License 0020 */ 0021 0022 /** Zend_Form_Element_Xhtml */ 0023 // require_once 'Zend/Form/Element/Xhtml.php'; 0024 0025 /** @see Zend_Crypt_Math */ 0026 // require_once 'Zend/Crypt/Math.php'; 0027 0028 /** 0029 * CSRF form protection 0030 * 0031 * @category Zend 0032 * @package Zend_Form 0033 * @subpackage Element 0034 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0035 * @license http://framework.zend.com/license/new-bsd New BSD License 0036 * @version $Id$ 0037 */ 0038 class Zend_Form_Element_Hash extends Zend_Form_Element_Xhtml 0039 { 0040 /** 0041 * Use formHidden view helper by default 0042 * @var string 0043 */ 0044 public $helper = 'formHidden'; 0045 0046 /** 0047 * Actual hash used. 0048 * 0049 * @var mixed 0050 */ 0051 protected $_hash; 0052 0053 /** 0054 * Salt for CSRF token 0055 * @var string 0056 */ 0057 protected $_salt = 'salt'; 0058 0059 /** 0060 * @var Zend_Session_Namespace 0061 */ 0062 protected $_session; 0063 0064 /** 0065 * TTL for CSRF token 0066 * @var int 0067 */ 0068 protected $_timeout = 300; 0069 0070 /** 0071 * Constructor 0072 * 0073 * Creates session namespace for CSRF token, and adds validator for CSRF 0074 * token. 0075 * 0076 * @param string|array|Zend_Config $spec 0077 * @param array|Zend_Config $options 0078 * @return void 0079 */ 0080 public function __construct($spec, $options = null) 0081 { 0082 parent::__construct($spec, $options); 0083 0084 $this->setAllowEmpty(false) 0085 ->setRequired(true) 0086 ->initCsrfValidator(); 0087 } 0088 0089 /** 0090 * Set session object 0091 * 0092 * @param Zend_Session_Namespace $session 0093 * @return Zend_Form_Element_Hash 0094 */ 0095 public function setSession($session) 0096 { 0097 $this->_session = $session; 0098 return $this; 0099 } 0100 0101 /** 0102 * Get session object 0103 * 0104 * Instantiate session object if none currently exists 0105 * 0106 * @return Zend_Session_Namespace 0107 */ 0108 public function getSession() 0109 { 0110 if (null === $this->_session) { 0111 // require_once 'Zend/Session/Namespace.php'; 0112 $this->_session = new Zend_Session_Namespace($this->getSessionName()); 0113 } 0114 return $this->_session; 0115 } 0116 0117 /** 0118 * Initialize CSRF validator 0119 * 0120 * Creates Session namespace, and initializes CSRF token in session. 0121 * Additionally, adds validator for validating CSRF token. 0122 * 0123 * @return Zend_Form_Element_Hash 0124 */ 0125 public function initCsrfValidator() 0126 { 0127 $session = $this->getSession(); 0128 if (isset($session->hash)) { 0129 $rightHash = $session->hash; 0130 } else { 0131 $rightHash = null; 0132 } 0133 0134 $this->addValidator('Identical', true, array($rightHash)); 0135 return $this; 0136 } 0137 0138 /** 0139 * Salt for CSRF token 0140 * 0141 * @param string $salt 0142 * @return Zend_Form_Element_Hash 0143 */ 0144 public function setSalt($salt) 0145 { 0146 $this->_salt = (string) $salt; 0147 return $this; 0148 } 0149 0150 /** 0151 * Retrieve salt for CSRF token 0152 * 0153 * @return string 0154 */ 0155 public function getSalt() 0156 { 0157 return $this->_salt; 0158 } 0159 0160 /** 0161 * Retrieve CSRF token 0162 * 0163 * If no CSRF token currently exists, generates one. 0164 * 0165 * @return string 0166 */ 0167 public function getHash() 0168 { 0169 if (null === $this->_hash) { 0170 $this->_generateHash(); 0171 } 0172 return $this->_hash; 0173 } 0174 0175 /** 0176 * Get session namespace for CSRF token 0177 * 0178 * Generates a session namespace based on salt, element name, and class. 0179 * 0180 * @return string 0181 */ 0182 public function getSessionName() 0183 { 0184 return __CLASS__ . '_' . $this->getSalt() . '_' . $this->getName(); 0185 } 0186 0187 /** 0188 * Set timeout for CSRF session token 0189 * 0190 * @param int $ttl 0191 * @return Zend_Form_Element_Hash 0192 */ 0193 public function setTimeout($ttl) 0194 { 0195 $this->_timeout = (int) $ttl; 0196 return $this; 0197 } 0198 0199 /** 0200 * Get CSRF session token timeout 0201 * 0202 * @return int 0203 */ 0204 public function getTimeout() 0205 { 0206 return $this->_timeout; 0207 } 0208 0209 /** 0210 * Override getLabel() to always be empty 0211 * 0212 * @return null 0213 */ 0214 public function getLabel() 0215 { 0216 return null; 0217 } 0218 0219 /** 0220 * Initialize CSRF token in session 0221 * 0222 * @return void 0223 */ 0224 public function initCsrfToken() 0225 { 0226 $session = $this->getSession(); 0227 $session->setExpirationHops(1, null, true); 0228 $session->setExpirationSeconds($this->getTimeout()); 0229 $session->hash = $this->getHash(); 0230 } 0231 0232 /** 0233 * Render CSRF token in form 0234 * 0235 * @param Zend_View_Interface $view 0236 * @return string 0237 */ 0238 public function render(Zend_View_Interface $view = null) 0239 { 0240 $this->initCsrfToken(); 0241 return parent::render($view); 0242 } 0243 0244 /** 0245 * Generate CSRF token 0246 * 0247 * Generates CSRF token and stores both in {@link $_hash} and element 0248 * value. 0249 * 0250 * @return void 0251 */ 0252 protected function _generateHash() 0253 { 0254 $this->_hash = md5( 0255 Zend_Crypt_Math::randBytes(32) 0256 ); 0257 $this->setValue($this->_hash); 0258 } 0259 }