Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 289531f

Browse filesBrowse files
jameshalsallfabpot
authored andcommitted
[Form] Skip CSRF validation on form when POST max size is exceeded
1 parent 4590759 commit 289531f
Copy full SHA for 289531f

File tree

Expand file treeCollapse file tree

7 files changed

+58
-12
lines changed
Filter options
Expand file treeCollapse file tree

7 files changed

+58
-12
lines changed

‎src/Symfony/Bundle/FrameworkBundle/Resources/config/form_csrf.xml

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Resources/config/form_csrf.xml
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
<argument>%form.type_extension.csrf.field_name%</argument>
1717
<argument type="service" id="translator.default" />
1818
<argument>%validator.translation_domain%</argument>
19+
<argument type="service" id="form.server_params" />
1920
</service>
2021
</services>
2122
</container>

‎src/Symfony/Component/Form/Extension/Csrf/EventListener/CsrfValidationListener.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Form/Extension/Csrf/EventListener/CsrfValidationListener.php
+10-2Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use Symfony\Component\Form\FormEvents;
1919
use Symfony\Component\Form\FormError;
2020
use Symfony\Component\Form\FormEvent;
21+
use Symfony\Component\Form\Util\ServerParams;
2122
use Symfony\Component\Security\Csrf\CsrfToken;
2223
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
2324
use Symfony\Component\Translation\TranslatorInterface;
@@ -68,14 +69,19 @@ class CsrfValidationListener implements EventSubscriberInterface
6869
*/
6970
private $translationDomain;
7071

72+
/**
73+
* @var ServerParams
74+
*/
75+
private $serverParams;
76+
7177
public static function getSubscribedEvents()
7278
{
7379
return array(
7480
FormEvents::PRE_SUBMIT => 'preSubmit',
7581
);
7682
}
7783

78-
public function __construct($fieldName, $tokenManager, $tokenId, $errorMessage, TranslatorInterface $translator = null, $translationDomain = null)
84+
public function __construct($fieldName, $tokenManager, $tokenId, $errorMessage, TranslatorInterface $translator = null, $translationDomain = null, ServerParams $serverParams = null)
7985
{
8086
if ($tokenManager instanceof CsrfProviderInterface) {
8187
$tokenManager = new CsrfProviderAdapter($tokenManager);
@@ -89,13 +95,15 @@ public function __construct($fieldName, $tokenManager, $tokenId, $errorMessage,
8995
$this->errorMessage = $errorMessage;
9096
$this->translator = $translator;
9197
$this->translationDomain = $translationDomain;
98+
$this->serverParams = $serverParams ?: new ServerParams();
9299
}
93100

94101
public function preSubmit(FormEvent $event)
95102
{
96103
$form = $event->getForm();
104+
$postRequestSizeExceeded = $form->getConfig()->getMethod() === 'POST' && $this->serverParams->hasPostMaxSizeBeenExceeded();
97105

98-
if ($form->isRoot() && $form->getConfig()->getOption('compound')) {
106+
if ($form->isRoot() && $form->getConfig()->getOption('compound') && !$postRequestSizeExceeded) {
99107
$data = $event->getData();
100108

101109
if (!isset($data[$this->fieldName]) || !$this->tokenManager->isTokenValid(new CsrfToken($this->tokenId, $data[$this->fieldName]))) {

‎src/Symfony/Component/Form/Extension/Csrf/Type/FormTypeCsrfExtension.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Form/Extension/Csrf/Type/FormTypeCsrfExtension.php
+10-2Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
use Symfony\Component\Form\FormBuilderInterface;
2121
use Symfony\Component\Form\FormView;
2222
use Symfony\Component\Form\FormInterface;
23+
use Symfony\Component\Form\Util\ServerParams;
2324
use Symfony\Component\OptionsResolver\Options;
2425
use Symfony\Component\OptionsResolver\OptionsResolver;
2526
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
@@ -55,7 +56,12 @@ class FormTypeCsrfExtension extends AbstractTypeExtension
5556
*/
5657
private $translationDomain;
5758

58-
public function __construct($defaultTokenManager, $defaultEnabled = true, $defaultFieldName = '_token', TranslatorInterface $translator = null, $translationDomain = null)
59+
/**
60+
* @var ServerParams
61+
*/
62+
private $serverParams;
63+
64+
public function __construct($defaultTokenManager, $defaultEnabled = true, $defaultFieldName = '_token', TranslatorInterface $translator = null, $translationDomain = null, ServerParams $serverParams = null)
5965
{
6066
if ($defaultTokenManager instanceof CsrfProviderInterface) {
6167
$defaultTokenManager = new CsrfProviderAdapter($defaultTokenManager);
@@ -68,6 +74,7 @@ public function __construct($defaultTokenManager, $defaultEnabled = true, $defau
6874
$this->defaultFieldName = $defaultFieldName;
6975
$this->translator = $translator;
7076
$this->translationDomain = $translationDomain;
77+
$this->serverParams = $serverParams;
7178
}
7279

7380
/**
@@ -89,7 +96,8 @@ public function buildForm(FormBuilderInterface $builder, array $options)
8996
$options['csrf_token_id'] ?: ($builder->getName() ?: get_class($builder->getType()->getInnerType())),
9097
$options['csrf_message'],
9198
$this->translator,
92-
$this->translationDomain
99+
$this->translationDomain,
100+
$this->serverParams
93101
))
94102
;
95103
}

‎src/Symfony/Component/Form/Extension/HttpFoundation/HttpFoundationRequestHandler.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Form/Extension/HttpFoundation/HttpFoundationRequestHandler.php
+1-4Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,7 @@ public function handleRequest(FormInterface $form, $request = null)
7373
// Mark the form with an error if the uploaded size was too large
7474
// This is done here and not in FormValidator because $_POST is
7575
// empty when that error occurs. Hence the form is never submitted.
76-
$contentLength = $this->serverParams->getContentLength();
77-
$maxContentLength = $this->serverParams->getPostMaxSize();
78-
79-
if (!empty($maxContentLength) && $contentLength > $maxContentLength) {
76+
if ($this->serverParams->hasPostMaxSizeBeenExceeded()) {
8077
// Submit the form, but don't clear the default values
8178
$form->submit(null, false);
8279

‎src/Symfony/Component/Form/NativeRequestHandler.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Form/NativeRequestHandler.php
+1-4Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,7 @@ public function handleRequest(FormInterface $form, $request = null)
8181
// Mark the form with an error if the uploaded size was too large
8282
// This is done here and not in FormValidator because $_POST is
8383
// empty when that error occurs. Hence the form is never submitted.
84-
$contentLength = $this->serverParams->getContentLength();
85-
$maxContentLength = $this->serverParams->getPostMaxSize();
86-
87-
if (!empty($maxContentLength) && $contentLength > $maxContentLength) {
84+
if ($this->serverParams->hasPostMaxSizeBeenExceeded()) {
8885
// Submit the form, but don't clear the default values
8986
$form->submit(null, false);
9087

‎src/Symfony/Component/Form/Tests/Extension/Csrf/EventListener/CsrfValidationListenerTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Form/Tests/Extension/Csrf/EventListener/CsrfValidationListenerTest.php
+22Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Component\Form\Tests\Extension\Csrf\EventListener;
1313

14+
use Symfony\Component\Form\Form;
1415
use Symfony\Component\Form\FormBuilder;
1516
use Symfony\Component\Form\FormEvent;
1617
use Symfony\Component\Form\Extension\Csrf\EventListener\CsrfValidationListener;
@@ -72,4 +73,25 @@ public function testStringFormData()
7273
// Validate accordingly
7374
$this->assertSame($data, $event->getData());
7475
}
76+
77+
public function testMaxPostSizeExceeded()
78+
{
79+
$serverParams = $this
80+
->getMockBuilder('\Symfony\Component\Form\Util\ServerParams')
81+
->disableOriginalConstructor()
82+
->getMock()
83+
;
84+
85+
$serverParams
86+
->expects($this->once())
87+
->method('hasPostMaxSizeBeenExceeded')
88+
->willReturn(true)
89+
;
90+
91+
$event = new FormEvent($this->form, array('csrf' => 'token'));
92+
$validation = new CsrfValidationListener('csrf', $this->tokenManager, 'unknown', 'Error message', null, null, $serverParams);
93+
94+
$validation->preSubmit($event);
95+
$this->assertEmpty($this->form->getErrors());
96+
}
7597
}

‎src/Symfony/Component/Form/Util/ServerParams.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Form/Util/ServerParams.php
+13Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,19 @@ public function __construct(RequestStack $requestStack = null)
2525
$this->requestStack = $requestStack;
2626
}
2727

28+
/**
29+
* Returns true if the POST max size has been exceeded in the request.
30+
*
31+
* @return bool
32+
*/
33+
public function hasPostMaxSizeBeenExceeded()
34+
{
35+
$contentLength = $this->getContentLength();
36+
$maxContentLength = $this->getPostMaxSize();
37+
38+
return $maxContentLength && $contentLength > $maxContentLength;
39+
}
40+
2841
/**
2942
* Returns maximum post size in bytes.
3043
*

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.