diff --git a/src/Symfony/Bridge/Twig/Extension/FormExtension.php b/src/Symfony/Bridge/Twig/Extension/FormExtension.php
index 25004e90fd0ec..b73212020a021 100644
--- a/src/Symfony/Bridge/Twig/Extension/FormExtension.php
+++ b/src/Symfony/Bridge/Twig/Extension/FormExtension.php
@@ -14,6 +14,7 @@
use Symfony\Bridge\Twig\TokenParser\FormThemeTokenParser;
use Symfony\Component\Form\FormView;
use Symfony\Component\Form\Exception\FormException;
+use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface;
use Symfony\Component\Form\Util\FormUtil;
/**
@@ -24,6 +25,7 @@
*/
class FormExtension extends \Twig_Extension
{
+ protected $csrfProvider;
protected $resources;
protected $blocks;
protected $environment;
@@ -31,8 +33,9 @@ class FormExtension extends \Twig_Extension
protected $varStack;
protected $template;
- public function __construct(array $resources = array())
+ public function __construct(CsrfProviderInterface $csrfProvider, array $resources = array())
{
+ $this->csrfProvider = $csrfProvider;
$this->themes = new \SplObjectStorage();
$this->varStack = array();
$this->blocks = new \SplObjectStorage();
@@ -81,6 +84,7 @@ public function getFunctions()
'form_label' => new \Twig_Function_Method($this, 'renderLabel', array('is_safe' => array('html'))),
'form_row' => new \Twig_Function_Method($this, 'renderRow', array('is_safe' => array('html'))),
'form_rest' => new \Twig_Function_Method($this, 'renderRest', array('is_safe' => array('html'))),
+ 'csrf_token' => new \Twig_Function_Method($this, 'getCsrfToken'),
'_form_is_choice_group' => new \Twig_Function_Method($this, 'isChoiceGroup', array('is_safe' => array('html'))),
'_form_is_choice_selected' => new \Twig_Function_Method($this, 'isChoiceSelected', array('is_safe' => array('html'))),
);
@@ -269,6 +273,34 @@ protected function render(FormView $view, $section, array $variables = array())
));
}
+ /**
+ * Returns a CSRF token.
+ *
+ * Use this helper for CSRF protection without the overhead of creating a
+ * form.
+ *
+ *
+ *
+ *
+ *
+ * Check the token in your action using the same intention.
+ *
+ *
+ * $csrfProvider = $this->get('form.csrf_provider');
+ * if (!$csrfProvider->isCsrfTokenValid('rm_user_'.$user->getId(), $token)) {
+ * throw new \RuntimeException('CSRF attack detected.');
+ * }
+ *
+ *
+ * @param string $intention The intention of the protected action
+ *
+ * @return string A CSRF token
+ */
+ public function getCsrfToken($intention)
+ {
+ return $this->csrfProvider->generateCsrfToken($intention);
+ }
+
/**
* Returns the name of the extension.
*
diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/templating_php.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/templating_php.xml
index 7c6f05a3af58f..9cc86bded20ff 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/templating_php.xml
+++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/templating_php.xml
@@ -97,6 +97,7 @@
+ * echo $view['form']->csrfToken('rm_user_'.$user->getId());
+ *
+ *
+ * Check the token in your action using the same intention.
+ *
+ *
+ * $csrfProvider = $this->get('form.csrf_provider');
+ * if (!$csrfProvider->isCsrfTokenValid('rm_user_'.$user->getId(), $token)) {
+ * throw new \RuntimeException('CSRF attack detected.');
+ * }
+ *
+ *
+ * @param string $intention The intention of the protected action
+ *
+ * @return string A CSRF token
+ */
+ public function csrfToken($intention)
+ {
+ return $this->csrfProvider->generateCsrfToken($intention);
+ }
+
/**
* Renders a template.
*
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/FormHelperDivLayoutTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/FormHelperDivLayoutTest.php
index 01b0bc614e381..7955f418ffcc3 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/FormHelperDivLayoutTest.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/FormHelperDivLayoutTest.php
@@ -37,7 +37,7 @@ protected function setUp()
$loader = new FilesystemLoader(array());
$engine = new PhpEngine($templateNameParser, $loader);
- $this->helper = new FormHelper($engine, array('FrameworkBundle:Form'));
+ $this->helper = new FormHelper($engine, $this->getMock('Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface'), array('FrameworkBundle:Form'));
$engine->setHelpers(array(
$this->helper,
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/FormHelperTableLayoutTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/FormHelperTableLayoutTest.php
index be209444ed772..da2223135c7d9 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/FormHelperTableLayoutTest.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/FormHelperTableLayoutTest.php
@@ -37,7 +37,7 @@ protected function setUp()
$loader = new FilesystemLoader(array());
$engine = new PhpEngine($templateNameParser, $loader);
- $this->helper = new FormHelper($engine, array(
+ $this->helper = new FormHelper($engine, $this->getMock('Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface'), array(
'FrameworkBundle:Form',
'FrameworkBundle:FormTable'
));
diff --git a/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml b/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml
index 7c24db417d300..36b4000ff89e3 100644
--- a/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml
+++ b/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml
@@ -75,6 +75,7 @@
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: