aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/symfony/form/Symfony/Component/Form/Extension/Csrf
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/symfony/form/Symfony/Component/Form/Extension/Csrf')
-rw-r--r--vendor/symfony/form/Symfony/Component/Form/Extension/Csrf/CsrfExtension.php64
-rw-r--r--vendor/symfony/form/Symfony/Component/Form/Extension/Csrf/CsrfProvider/CsrfProviderInterface.php49
-rw-r--r--vendor/symfony/form/Symfony/Component/Form/Extension/Csrf/CsrfProvider/DefaultCsrfProvider.php78
-rw-r--r--vendor/symfony/form/Symfony/Component/Form/Extension/Csrf/CsrfProvider/SessionCsrfProvider.php57
-rw-r--r--vendor/symfony/form/Symfony/Component/Form/Extension/Csrf/EventListener/CsrfValidationListener.php115
-rw-r--r--vendor/symfony/form/Symfony/Component/Form/Extension/Csrf/Type/FormTypeCsrfExtension.php129
6 files changed, 492 insertions, 0 deletions
diff --git a/vendor/symfony/form/Symfony/Component/Form/Extension/Csrf/CsrfExtension.php b/vendor/symfony/form/Symfony/Component/Form/Extension/Csrf/CsrfExtension.php
new file mode 100644
index 00000000..f9d9e40a
--- /dev/null
+++ b/vendor/symfony/form/Symfony/Component/Form/Extension/Csrf/CsrfExtension.php
@@ -0,0 +1,64 @@
1<?php
2
3/*
4 * This file is part of the Symfony package.
5 *
6 * (c) Fabien Potencier <fabien@symfony.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12namespace Symfony\Component\Form\Extension\Csrf;
13
14use Symfony\Component\Form\Extension\Csrf\Type;
15use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface;
16use Symfony\Component\Form\AbstractExtension;
17use Symfony\Component\Translation\TranslatorInterface;
18
19/**
20 * This extension protects forms by using a CSRF token.
21 *
22 * @author Bernhard Schussek <bschussek@gmail.com>
23 */
24class CsrfExtension extends AbstractExtension
25{
26 /**
27 * @var CsrfProviderInterface
28 */
29 private $csrfProvider;
30
31 /**
32 * @var TranslatorInterface
33 */
34 private $translator;
35
36 /**
37 * @var null|string
38 */
39 private $translationDomain;
40
41 /**
42 * Constructor.
43 *
44 * @param CsrfProviderInterface $csrfProvider The CSRF provider
45 * @param TranslatorInterface $translator The translator for translating error messages.
46 * @param null|string $translationDomain The translation domain for translating.
47 */
48 public function __construct(CsrfProviderInterface $csrfProvider, TranslatorInterface $translator = null, $translationDomain = null)
49 {
50 $this->csrfProvider = $csrfProvider;
51 $this->translator = $translator;
52 $this->translationDomain = $translationDomain;
53 }
54
55 /**
56 * {@inheritDoc}
57 */
58 protected function loadTypeExtensions()
59 {
60 return array(
61 new Type\FormTypeCsrfExtension($this->csrfProvider, true, '_token', $this->translator, $this->translationDomain),
62 );
63 }
64}
diff --git a/vendor/symfony/form/Symfony/Component/Form/Extension/Csrf/CsrfProvider/CsrfProviderInterface.php b/vendor/symfony/form/Symfony/Component/Form/Extension/Csrf/CsrfProvider/CsrfProviderInterface.php
new file mode 100644
index 00000000..7143b130
--- /dev/null
+++ b/vendor/symfony/form/Symfony/Component/Form/Extension/Csrf/CsrfProvider/CsrfProviderInterface.php
@@ -0,0 +1,49 @@
1<?php
2
3/*
4 * This file is part of the Symfony package.
5 *
6 * (c) Fabien Potencier <fabien@symfony.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12namespace Symfony\Component\Form\Extension\Csrf\CsrfProvider;
13
14/**
15 * Marks classes able to provide CSRF protection
16 *
17 * You can generate a CSRF token by using the method generateCsrfToken(). To
18 * this method you should pass a value that is unique to the page that should
19 * be secured against CSRF attacks. This value doesn't necessarily have to be
20 * secret. Implementations of this interface are responsible for adding more
21 * secret information.
22 *
23 * If you want to secure a form submission against CSRF attacks, you could
24 * supply an "intention" string. This way you make sure that the form can only
25 * be submitted to pages that are designed to handle the form, that is, that use
26 * the same intention string to validate the CSRF token with isCsrfTokenValid().
27 *
28 * @author Bernhard Schussek <bschussek@gmail.com>
29 */
30interface CsrfProviderInterface
31{
32 /**
33 * Generates a CSRF token for a page of your application.
34 *
35 * @param string $intention Some value that identifies the action intention
36 * (i.e. "authenticate"). Doesn't have to be a secret value.
37 */
38 public function generateCsrfToken($intention);
39
40 /**
41 * Validates a CSRF token.
42 *
43 * @param string $intention The intention used when generating the CSRF token
44 * @param string $token The token supplied by the browser
45 *
46 * @return Boolean Whether the token supplied by the browser is correct
47 */
48 public function isCsrfTokenValid($intention, $token);
49}
diff --git a/vendor/symfony/form/Symfony/Component/Form/Extension/Csrf/CsrfProvider/DefaultCsrfProvider.php b/vendor/symfony/form/Symfony/Component/Form/Extension/Csrf/CsrfProvider/DefaultCsrfProvider.php
new file mode 100644
index 00000000..5354886c
--- /dev/null
+++ b/vendor/symfony/form/Symfony/Component/Form/Extension/Csrf/CsrfProvider/DefaultCsrfProvider.php
@@ -0,0 +1,78 @@
1<?php
2
3/*
4 * This file is part of the Symfony package.
5 *
6 * (c) Fabien Potencier <fabien@symfony.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12namespace Symfony\Component\Form\Extension\Csrf\CsrfProvider;
13
14/**
15 * Default implementation of CsrfProviderInterface.
16 *
17 * This provider uses the session ID returned by session_id() as well as a
18 * user-defined secret value to secure the CSRF token.
19 *
20 * @author Bernhard Schussek <bschussek@gmail.com>
21 */
22class DefaultCsrfProvider implements CsrfProviderInterface
23{
24 /**
25 * A secret value used for generating the CSRF token
26 * @var string
27 */
28 protected $secret;
29
30 /**
31 * Initializes the provider with a secret value
32 *
33 * A recommended value for the secret is a generated value with at least
34 * 32 characters and mixed letters, digits and special characters.
35 *
36 * @param string $secret A secret value included in the CSRF token
37 */
38 public function __construct($secret)
39 {
40 $this->secret = $secret;
41 }
42
43 /**
44 * {@inheritDoc}
45 */
46 public function generateCsrfToken($intention)
47 {
48 return sha1($this->secret.$intention.$this->getSessionId());
49 }
50
51 /**
52 * {@inheritDoc}
53 */
54 public function isCsrfTokenValid($intention, $token)
55 {
56 return $token === $this->generateCsrfToken($intention);
57 }
58
59 /**
60 * Returns the ID of the user session.
61 *
62 * Automatically starts the session if necessary.
63 *
64 * @return string The session ID
65 */
66 protected function getSessionId()
67 {
68 if (version_compare(PHP_VERSION, '5.4', '>=')) {
69 if (PHP_SESSION_NONE === session_status()) {
70 session_start();
71 }
72 } elseif (!session_id()) {
73 session_start();
74 }
75
76 return session_id();
77 }
78}
diff --git a/vendor/symfony/form/Symfony/Component/Form/Extension/Csrf/CsrfProvider/SessionCsrfProvider.php b/vendor/symfony/form/Symfony/Component/Form/Extension/Csrf/CsrfProvider/SessionCsrfProvider.php
new file mode 100644
index 00000000..ea1fa585
--- /dev/null
+++ b/vendor/symfony/form/Symfony/Component/Form/Extension/Csrf/CsrfProvider/SessionCsrfProvider.php
@@ -0,0 +1,57 @@
1<?php
2
3/*
4 * This file is part of the Symfony package.
5 *
6 * (c) Fabien Potencier <fabien@symfony.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12namespace Symfony\Component\Form\Extension\Csrf\CsrfProvider;
13
14use Symfony\Component\HttpFoundation\Session\Session;
15
16/**
17 * This provider uses a Symfony2 Session object to retrieve the user's
18 * session ID.
19 *
20 * @see DefaultCsrfProvider
21 *
22 * @author Bernhard Schussek <bschussek@gmail.com>
23 */
24class SessionCsrfProvider extends DefaultCsrfProvider
25{
26 /**
27 * The user session from which the session ID is returned
28 * @var Session
29 */
30 protected $session;
31
32 /**
33 * Initializes the provider with a Session object and a secret value.
34 *
35 * A recommended value for the secret is a generated value with at least
36 * 32 characters and mixed letters, digits and special characters.
37 *
38 * @param Session $session The user session
39 * @param string $secret A secret value included in the CSRF token
40 */
41 public function __construct(Session $session, $secret)
42 {
43 parent::__construct($secret);
44
45 $this->session = $session;
46 }
47
48 /**
49 * {@inheritdoc}
50 */
51 protected function getSessionId()
52 {
53 $this->session->start();
54
55 return $this->session->getId();
56 }
57}
diff --git a/vendor/symfony/form/Symfony/Component/Form/Extension/Csrf/EventListener/CsrfValidationListener.php b/vendor/symfony/form/Symfony/Component/Form/Extension/Csrf/EventListener/CsrfValidationListener.php
new file mode 100644
index 00000000..547e9d75
--- /dev/null
+++ b/vendor/symfony/form/Symfony/Component/Form/Extension/Csrf/EventListener/CsrfValidationListener.php
@@ -0,0 +1,115 @@
1<?php
2
3/*
4 * This file is part of the Symfony package.
5 *
6 * (c) Fabien Potencier <fabien@symfony.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12namespace Symfony\Component\Form\Extension\Csrf\EventListener;
13
14use Symfony\Component\EventDispatcher\EventSubscriberInterface;
15use Symfony\Component\Form\FormEvents;
16use Symfony\Component\Form\FormError;
17use Symfony\Component\Form\FormEvent;
18use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface;
19use Symfony\Component\Translation\TranslatorInterface;
20
21/**
22 * @author Bernhard Schussek <bschussek@gmail.com>
23 */
24class CsrfValidationListener implements EventSubscriberInterface
25{
26 /**
27 * The name of the CSRF field
28 * @var string
29 */
30 private $fieldName;
31
32 /**
33 * The provider for generating and validating CSRF tokens
34 * @var CsrfProviderInterface
35 */
36 private $csrfProvider;
37
38 /**
39 * A text mentioning the intention of the CSRF token
40 *
41 * Validation of the token will only succeed if it was generated in the
42 * same session and with the same intention.
43 *
44 * @var string
45 */
46 private $intention;
47
48 /**
49 * The message displayed in case of an error.
50 * @var string
51 */
52 private $errorMessage;
53
54 /**
55 * @var TranslatorInterface
56 */
57 private $translator;
58
59 /**
60 * @var null|string
61 */
62 private $translationDomain;
63
64 public static function getSubscribedEvents()
65 {
66 return array(
67 FormEvents::PRE_SUBMIT => 'preSubmit',
68 );
69 }
70
71 public function __construct($fieldName, CsrfProviderInterface $csrfProvider, $intention, $errorMessage, TranslatorInterface $translator = null, $translationDomain = null)
72 {
73 $this->fieldName = $fieldName;
74 $this->csrfProvider = $csrfProvider;
75 $this->intention = $intention;
76 $this->errorMessage = $errorMessage;
77 $this->translator = $translator;
78 $this->translationDomain = $translationDomain;
79 }
80
81 public function preSubmit(FormEvent $event)
82 {
83 $form = $event->getForm();
84 $data = $event->getData();
85
86 if ($form->isRoot() && $form->getConfig()->getOption('compound')) {
87 if (!isset($data[$this->fieldName]) || !$this->csrfProvider->isCsrfTokenValid($this->intention, $data[$this->fieldName])) {
88 $errorMessage = $this->errorMessage;
89
90 if (null !== $this->translator) {
91 $errorMessage = $this->translator->trans($errorMessage, array(), $this->translationDomain);
92 }
93
94 $form->addError(new FormError($errorMessage));
95 }
96
97 if (is_array($data)) {
98 unset($data[$this->fieldName]);
99 }
100 }
101
102 $event->setData($data);
103 }
104
105 /**
106 * Alias of {@link preSubmit()}.
107 *
108 * @deprecated Deprecated since version 2.3, to be removed in 3.0. Use
109 * {@link preSubmit()} instead.
110 */
111 public function preBind(FormEvent $event)
112 {
113 $this->preSubmit($event);
114 }
115}
diff --git a/vendor/symfony/form/Symfony/Component/Form/Extension/Csrf/Type/FormTypeCsrfExtension.php b/vendor/symfony/form/Symfony/Component/Form/Extension/Csrf/Type/FormTypeCsrfExtension.php
new file mode 100644
index 00000000..336cf047
--- /dev/null
+++ b/vendor/symfony/form/Symfony/Component/Form/Extension/Csrf/Type/FormTypeCsrfExtension.php
@@ -0,0 +1,129 @@
1<?php
2
3/*
4 * This file is part of the Symfony package.
5 *
6 * (c) Fabien Potencier <fabien@symfony.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12namespace Symfony\Component\Form\Extension\Csrf\Type;
13
14use Symfony\Component\Form\AbstractTypeExtension;
15use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface;
16use Symfony\Component\Form\Extension\Csrf\EventListener\CsrfValidationListener;
17use Symfony\Component\Form\FormBuilderInterface;
18use Symfony\Component\Form\FormView;
19use Symfony\Component\Form\FormInterface;
20use Symfony\Component\OptionsResolver\OptionsResolverInterface;
21use Symfony\Component\Translation\TranslatorInterface;
22
23/**
24 * @author Bernhard Schussek <bschussek@gmail.com>
25 */
26class FormTypeCsrfExtension extends AbstractTypeExtension
27{
28 /**
29 * @var CsrfProviderInterface
30 */
31 private $defaultCsrfProvider;
32
33 /**
34 * @var Boolean
35 */
36 private $defaultEnabled;
37
38 /**
39 * @var string
40 */
41 private $defaultFieldName;
42
43 /**
44 * @var TranslatorInterface
45 */
46 private $translator;
47
48 /**
49 * @var null|string
50 */
51 private $translationDomain;
52
53 public function __construct(CsrfProviderInterface $defaultCsrfProvider, $defaultEnabled = true, $defaultFieldName = '_token', TranslatorInterface $translator = null, $translationDomain = null)
54 {
55 $this->defaultCsrfProvider = $defaultCsrfProvider;
56 $this->defaultEnabled = $defaultEnabled;
57 $this->defaultFieldName = $defaultFieldName;
58 $this->translator = $translator;
59 $this->translationDomain = $translationDomain;
60 }
61
62 /**
63 * Adds a CSRF field to the form when the CSRF protection is enabled.
64 *
65 * @param FormBuilderInterface $builder The form builder
66 * @param array $options The options
67 */
68 public function buildForm(FormBuilderInterface $builder, array $options)
69 {
70 if (!$options['csrf_protection']) {
71 return;
72 }
73
74 $builder
75 ->setAttribute('csrf_factory', $builder->getFormFactory())
76 ->addEventSubscriber(new CsrfValidationListener(
77 $options['csrf_field_name'],
78 $options['csrf_provider'],
79 $options['intention'],
80 $options['csrf_message'],
81 $this->translator,
82 $this->translationDomain
83 ))
84 ;
85 }
86
87 /**
88 * Adds a CSRF field to the root form view.
89 *
90 * @param FormView $view The form view
91 * @param FormInterface $form The form
92 * @param array $options The options
93 */
94 public function finishView(FormView $view, FormInterface $form, array $options)
95 {
96 if ($options['csrf_protection'] && !$view->parent && $options['compound']) {
97 $factory = $form->getConfig()->getAttribute('csrf_factory');
98 $data = $options['csrf_provider']->generateCsrfToken($options['intention']);
99
100 $csrfForm = $factory->createNamed($options['csrf_field_name'], 'hidden', $data, array(
101 'mapped' => false,
102 ));
103
104 $view->children[$options['csrf_field_name']] = $csrfForm->createView($view);
105 }
106 }
107
108 /**
109 * {@inheritDoc}
110 */
111 public function setDefaultOptions(OptionsResolverInterface $resolver)
112 {
113 $resolver->setDefaults(array(
114 'csrf_protection' => $this->defaultEnabled,
115 'csrf_field_name' => $this->defaultFieldName,
116 'csrf_provider' => $this->defaultCsrfProvider,
117 'csrf_message' => 'The CSRF token is invalid. Please try to resubmit the form.',
118 'intention' => 'unknown',
119 ));
120 }
121
122 /**
123 * {@inheritDoc}
124 */
125 public function getExtendedType()
126 {
127 return 'form';
128 }
129}