mirror of
				https://github.com/Icinga/icingaweb2.git
				synced 2025-10-31 03:14:31 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			89 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			89 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| // {{{ICINGA_LICENSE_HEADER}}}
 | |
| // {{{ICINGA_LICENSE_HEADER}}}
 | |
| 
 | |
| namespace Icinga\Web\Form\Element;
 | |
| 
 | |
| use Zend_Form_Element_Xhtml;
 | |
| use Icinga\Web\Session;
 | |
| use Icinga\Web\Form\InvalidCSRFTokenException;
 | |
| 
 | |
| /**
 | |
|  * CSRF counter measure element
 | |
|  *
 | |
|  * You must not set a value to successfully use this element, just give it a name and you're good to go.
 | |
|  */
 | |
| class CsrfCounterMeasure extends Zend_Form_Element_Xhtml
 | |
| {
 | |
|     /**
 | |
|      * Default form view helper to use for rendering
 | |
|      *
 | |
|      * @var string
 | |
|      */
 | |
|     public $helper = 'formHidden';
 | |
| 
 | |
|     /**
 | |
|      * Initialize this form element
 | |
|      */
 | |
|     public function init()
 | |
|     {
 | |
|         $this->setRequired(true); // Not requiring this element would not make any sense
 | |
|         $this->setIgnore(true); // We do not want this element's value being retrieved by Form::getValues()
 | |
|         $this->setDecorators(array('ViewHelper'));
 | |
|         $this->setValue($this->generateCsrfToken());
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Check whether $value is a valid CSRF token
 | |
|      *
 | |
|      * @param   string      $value          The value to check
 | |
|      * @param   mixed       $context        Context to use
 | |
|      *
 | |
|      * @return  bool                        True, in case the CSRF token is valid
 | |
|      *
 | |
|      * @throws  InvalidCSRFTokenException   In case the CSRF token is not valid
 | |
|      */
 | |
|     public function isValid($value, $context = null)
 | |
|     {
 | |
|         if (parent::isValid($value, $context) && $this->isValidCsrfToken($value)) {
 | |
|             return true;
 | |
|         }
 | |
| 
 | |
|         throw new InvalidCSRFTokenException();
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Check whether the given value is a valid CSRF token for the current session
 | |
|      *
 | |
|      * @param   string  $token  The CSRF token
 | |
|      *
 | |
|      * @return  bool
 | |
|      */
 | |
|     protected function isValidCsrfToken($token)
 | |
|     {
 | |
|         if (strpos($token, '|') === false) {
 | |
|             return false;
 | |
|         }
 | |
| 
 | |
|         list($seed, $hash) = explode('|', $token);
 | |
| 
 | |
|         if (false === is_numeric($seed)) {
 | |
|             return false;
 | |
|         }
 | |
| 
 | |
|         return $hash === hash('sha256', Session::getSession()->getId() . $seed);
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Generate a new (seed, token) pair
 | |
|      *
 | |
|      * @return  string
 | |
|      */
 | |
|     protected function generateCsrfToken()
 | |
|     {
 | |
|         $seed = mt_rand();
 | |
|         $hash = hash('sha256', Session::getSession()->getId() . $seed);
 | |
|         return sprintf('%s|%s', $seed, $hash);
 | |
|     }
 | |
| }
 |