|
1 <?php |
|
2 /** |
|
3 * Zend Framework |
|
4 * |
|
5 * LICENSE |
|
6 * |
|
7 * This source file is subject to the new BSD license that is bundled |
|
8 * with this package in the file LICENSE.txt. |
|
9 * It is also available through the world-wide-web at this URL: |
|
10 * http://framework.zend.com/license/new-bsd |
|
11 * If you did not receive a copy of the license and are unable to |
|
12 * obtain it through the world-wide-web, please send an email |
|
13 * to license@zend.com so we can send you a copy immediately. |
|
14 * |
|
15 * @category Zend |
|
16 * @package Zend_Form |
|
17 * @subpackage Element |
|
18 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) |
|
19 * @license http://framework.zend.com/license/new-bsd New BSD License |
|
20 */ |
|
21 |
|
22 /** Zend_Form_Element_Xhtml */ |
|
23 require_once 'Zend/Form/Element/Xhtml.php'; |
|
24 |
|
25 /** |
|
26 * CSRF form protection |
|
27 * |
|
28 * @category Zend |
|
29 * @package Zend_Form |
|
30 * @subpackage Element |
|
31 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) |
|
32 * @license http://framework.zend.com/license/new-bsd New BSD License |
|
33 * @version $Id: Hash.php 20096 2010-01-06 02:05:09Z bkarwin $ |
|
34 */ |
|
35 class Zend_Form_Element_Hash extends Zend_Form_Element_Xhtml |
|
36 { |
|
37 /** |
|
38 * Use formHidden view helper by default |
|
39 * @var string |
|
40 */ |
|
41 public $helper = 'formHidden'; |
|
42 |
|
43 /** |
|
44 * Actual hash used. |
|
45 * |
|
46 * @var mixed |
|
47 */ |
|
48 protected $_hash; |
|
49 |
|
50 /** |
|
51 * Salt for CSRF token |
|
52 * @var string |
|
53 */ |
|
54 protected $_salt = 'salt'; |
|
55 |
|
56 /** |
|
57 * @var Zend_Session_Namespace |
|
58 */ |
|
59 protected $_session; |
|
60 |
|
61 /** |
|
62 * TTL for CSRF token |
|
63 * @var int |
|
64 */ |
|
65 protected $_timeout = 300; |
|
66 |
|
67 /** |
|
68 * Constructor |
|
69 * |
|
70 * Creates session namespace for CSRF token, and adds validator for CSRF |
|
71 * token. |
|
72 * |
|
73 * @param string|array|Zend_Config $spec |
|
74 * @param array|Zend_Config $options |
|
75 * @return void |
|
76 */ |
|
77 public function __construct($spec, $options = null) |
|
78 { |
|
79 parent::__construct($spec, $options); |
|
80 |
|
81 $this->setAllowEmpty(false) |
|
82 ->setRequired(true) |
|
83 ->initCsrfValidator(); |
|
84 } |
|
85 |
|
86 /** |
|
87 * Set session object |
|
88 * |
|
89 * @param Zend_Session_Namespace $session |
|
90 * @return Zend_Form_Element_Hash |
|
91 */ |
|
92 public function setSession($session) |
|
93 { |
|
94 $this->_session = $session; |
|
95 return $this; |
|
96 } |
|
97 |
|
98 /** |
|
99 * Get session object |
|
100 * |
|
101 * Instantiate session object if none currently exists |
|
102 * |
|
103 * @return Zend_Session_Namespace |
|
104 */ |
|
105 public function getSession() |
|
106 { |
|
107 if (null === $this->_session) { |
|
108 require_once 'Zend/Session/Namespace.php'; |
|
109 $this->_session = new Zend_Session_Namespace($this->getSessionName()); |
|
110 } |
|
111 return $this->_session; |
|
112 } |
|
113 |
|
114 /** |
|
115 * Initialize CSRF validator |
|
116 * |
|
117 * Creates Session namespace, and initializes CSRF token in session. |
|
118 * Additionally, adds validator for validating CSRF token. |
|
119 * |
|
120 * @return Zend_Form_Element_Hash |
|
121 */ |
|
122 public function initCsrfValidator() |
|
123 { |
|
124 $session = $this->getSession(); |
|
125 if (isset($session->hash)) { |
|
126 $rightHash = $session->hash; |
|
127 } else { |
|
128 $rightHash = null; |
|
129 } |
|
130 |
|
131 $this->addValidator('Identical', true, array($rightHash)); |
|
132 return $this; |
|
133 } |
|
134 |
|
135 /** |
|
136 * Salt for CSRF token |
|
137 * |
|
138 * @param string $salt |
|
139 * @return Zend_Form_Element_Hash |
|
140 */ |
|
141 public function setSalt($salt) |
|
142 { |
|
143 $this->_salt = (string) $salt; |
|
144 return $this; |
|
145 } |
|
146 |
|
147 /** |
|
148 * Retrieve salt for CSRF token |
|
149 * |
|
150 * @return string |
|
151 */ |
|
152 public function getSalt() |
|
153 { |
|
154 return $this->_salt; |
|
155 } |
|
156 |
|
157 /** |
|
158 * Retrieve CSRF token |
|
159 * |
|
160 * If no CSRF token currently exists, generates one. |
|
161 * |
|
162 * @return string |
|
163 */ |
|
164 public function getHash() |
|
165 { |
|
166 if (null === $this->_hash) { |
|
167 $this->_generateHash(); |
|
168 } |
|
169 return $this->_hash; |
|
170 } |
|
171 |
|
172 /** |
|
173 * Get session namespace for CSRF token |
|
174 * |
|
175 * Generates a session namespace based on salt, element name, and class. |
|
176 * |
|
177 * @return string |
|
178 */ |
|
179 public function getSessionName() |
|
180 { |
|
181 return __CLASS__ . '_' . $this->getSalt() . '_' . $this->getName(); |
|
182 } |
|
183 |
|
184 /** |
|
185 * Set timeout for CSRF session token |
|
186 * |
|
187 * @param int $ttl |
|
188 * @return Zend_Form_Element_Hash |
|
189 */ |
|
190 public function setTimeout($ttl) |
|
191 { |
|
192 $this->_timeout = (int) $ttl; |
|
193 return $this; |
|
194 } |
|
195 |
|
196 /** |
|
197 * Get CSRF session token timeout |
|
198 * |
|
199 * @return int |
|
200 */ |
|
201 public function getTimeout() |
|
202 { |
|
203 return $this->_timeout; |
|
204 } |
|
205 |
|
206 /** |
|
207 * Override getLabel() to always be empty |
|
208 * |
|
209 * @return null |
|
210 */ |
|
211 public function getLabel() |
|
212 { |
|
213 return null; |
|
214 } |
|
215 |
|
216 /** |
|
217 * Initialize CSRF token in session |
|
218 * |
|
219 * @return void |
|
220 */ |
|
221 public function initCsrfToken() |
|
222 { |
|
223 $session = $this->getSession(); |
|
224 $session->setExpirationHops(1, null, true); |
|
225 $session->setExpirationSeconds($this->getTimeout()); |
|
226 $session->hash = $this->getHash(); |
|
227 } |
|
228 |
|
229 /** |
|
230 * Render CSRF token in form |
|
231 * |
|
232 * @param Zend_View_Interface $view |
|
233 * @return string |
|
234 */ |
|
235 public function render(Zend_View_Interface $view = null) |
|
236 { |
|
237 $this->initCsrfToken(); |
|
238 return parent::render($view); |
|
239 } |
|
240 |
|
241 /** |
|
242 * Generate CSRF token |
|
243 * |
|
244 * Generates CSRF token and stores both in {@link $_hash} and element |
|
245 * value. |
|
246 * |
|
247 * @return void |
|
248 */ |
|
249 protected function _generateHash() |
|
250 { |
|
251 $this->_hash = md5( |
|
252 mt_rand(1,1000000) |
|
253 . $this->getSalt() |
|
254 . $this->getName() |
|
255 . mt_rand(1,1000000) |
|
256 ); |
|
257 $this->setValue($this->_hash); |
|
258 } |
|
259 } |