1: <?php
2:
3: /**
4: * This file is part of the Nette Framework (http://nette.org)
5: * Copyright (c) 2004 David Grudl (http://davidgrudl.com)
6: */
7:
8: namespace Nette\Forms\Controls;
9:
10: use Nette;
11:
12:
13: /**
14: * @author Filip Procházka
15: */
16: class CsrfProtection extends HiddenField
17: {
18: const PROTECTION = 'Nette\Forms\Controls\CsrfProtection::validateCsrf';
19:
20: /** @var Nette\Http\Session */
21: public $session;
22:
23:
24: /**
25: * @param string
26: * @param int
27: */
28: public function __construct($message)
29: {
30: parent::__construct();
31: $this->setOmitted()->addRule(self::PROTECTION, $message);
32: $this->monitor('Nette\Application\UI\Presenter');
33: }
34:
35:
36: protected function attached($parent)
37: {
38: parent::attached($parent);
39: if (!$this->session && $parent instanceof Nette\Application\UI\Presenter) {
40: $this->session = $parent->getSession();
41: }
42: }
43:
44:
45: /**
46: * @return string
47: */
48: public function getToken()
49: {
50: $session = $this->getSession()->getSection(__CLASS__);
51: if (!isset($session->token)) {
52: $session->token = Nette\Utils\Random::generate();
53: }
54: return $session->token;
55: }
56:
57:
58: /**
59: * @return string
60: */
61: private function generateToken($random = NULL)
62: {
63: if ($random === NULL) {
64: $random = Nette\Utils\Random::generate(10);
65: }
66: return $random . base64_encode(sha1($this->getToken() . $random, TRUE));
67: }
68:
69:
70: /**
71: * Generates control's HTML element.
72: *
73: * @return Nette\Utils\Html
74: */
75: public function getControl()
76: {
77: return parent::getControl()->value($this->generateToken());
78: }
79:
80:
81: /**
82: * @return bool
83: */
84: public static function validateCsrf(CsrfProtection $control)
85: {
86: $value = $control->getValue();
87: return $control->generateToken(substr($value, 0, 10)) === $value;
88: }
89:
90:
91: /********************* backend ****************d*g**/
92:
93:
94: /**
95: * @return Nette\Http\Session
96: */
97: private function getSession()
98: {
99: if (!$this->session) {
100: $this->session = new Nette\Http\Session($this->getForm()->httpRequest, new Nette\Http\Response);
101: }
102: return $this->session;
103: }
104:
105: }
106: