Skip to content

Commit 294c833

Browse files
committed
Form: POST form checks Http\Request::isSameSite() as CSRF protection
1 parent d3b5bf6 commit 294c833

31 files changed

+102
-1
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
"require": {
1818
"php": ">=7.2 <8.1",
1919
"nette/component-model": "^3.0",
20-
"nette/http": "^3.0",
20+
"nette/http": "^3.1",
2121
"nette/utils": "^3.2"
2222
},
2323
"require-dev": {

src/Forms/Form.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,9 @@ class Form extends Container implements Nette\HtmlStringable
9696
/** @internal @var Nette\Http\IRequest used only by standalone form */
9797
public $httpRequest;
9898

99+
/** @var bool */
100+
protected $crossOrigin = false;
101+
99102
/** @var mixed or null meaning: not detected yet */
100103
private $submittedBy;
101104

@@ -214,6 +217,15 @@ public function setHtmlAttribute(string $name, $value = true)
214217
}
215218

216219

220+
/**
221+
* Disables CSRF protection using a SameSite cookie.
222+
*/
223+
public function allowCrossOrigin(): void
224+
{
225+
$this->crossOrigin = true;
226+
}
227+
228+
217229
/**
218230
* Cross-Site Request Forgery (CSRF) form protection.
219231
*/
@@ -474,6 +486,9 @@ protected function receiveHttpData(): ?array
474486
}
475487

476488
if ($httpRequest->isMethod('post')) {
489+
if (!$this->crossOrigin && !$httpRequest->isSameSite()) {
490+
return null;
491+
}
477492
$data = Nette\Utils\Arrays::mergeTree($httpRequest->getPost(), $httpRequest->getFiles());
478493
} else {
479494
$data = $httpRequest->getQuery();
@@ -658,6 +673,7 @@ private function getHttpRequest(): Nette\Http\IRequest
658673
if (!$this->httpRequest) {
659674
$factory = new Nette\Http\RequestFactory;
660675
$this->httpRequest = $factory->createHttpRequest();
676+
Nette\Http\Helpers::initCookie($this->httpRequest, new Nette\Http\Response);
661677
}
662678
return $this->httpRequest;
663679
}

tests/Forms/Container.values.ArrayHash.phpt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use Tester\Assert;
1010
require __DIR__ . '/../bootstrap.php';
1111

1212

13+
$_COOKIE[Nette\Http\Helpers::STRICT_COOKIE_NAME] = '1';
1314
$_POST = [
1415
'title' => 'sent title',
1516
'first' => [

tests/Forms/Container.values.array.phpt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use Tester\Assert;
1010
require __DIR__ . '/../bootstrap.php';
1111

1212

13+
$_COOKIE[Nette\Http\Helpers::STRICT_COOKIE_NAME] = '1';
1314
$_POST = [
1415
'title' => 'sent title',
1516
'first' => [

tests/Forms/Container.values.mapping.phpt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ function hydrate(string $class, array $data)
5050
}
5151

5252

53+
$_COOKIE[Nette\Http\Helpers::STRICT_COOKIE_NAME] = '1';
5354
$_POST = [
5455
'title' => 'sent title',
5556
'first' => [

tests/Forms/Controls.BaseControl.phpt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ test('disabled', function () {
126126
test('disabled & submitted', function () {
127127
$_SERVER['REQUEST_METHOD'] = 'POST';
128128
$_POST = ['disabled' => 'submitted value'];
129+
$_COOKIE[Nette\Http\Helpers::STRICT_COOKIE_NAME] = '1';
129130

130131
$form = new Form;
131132
$form->addText('disabled')

tests/Forms/Controls.Button.loadData.phpt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ require __DIR__ . '/../bootstrap.php';
1616
before(function () {
1717
$_SERVER['REQUEST_METHOD'] = 'POST';
1818
$_POST = $_FILES = [];
19+
$_COOKIE[Nette\Http\Helpers::STRICT_COOKIE_NAME] = '1';
1920
});
2021

2122

tests/Forms/Controls.Checkbox.loadData.phpt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ require __DIR__ . '/../bootstrap.php';
1616
before(function () {
1717
$_SERVER['REQUEST_METHOD'] = 'POST';
1818
$_POST = $_FILES = [];
19+
$_COOKIE[Nette\Http\Helpers::STRICT_COOKIE_NAME] = '1';
1920
});
2021

2122

tests/Forms/Controls.CheckboxList.loadData.phpt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ require __DIR__ . '/../bootstrap.php';
1818
before(function () {
1919
$_SERVER['REQUEST_METHOD'] = 'POST';
2020
$_POST = $_FILES = [];
21+
$_COOKIE[Nette\Http\Helpers::STRICT_COOKIE_NAME] = '1';
2122
});
2223

2324

tests/Forms/Controls.ChoiceControl.loadData.phpt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ class ChoiceControl extends Nette\Forms\Controls\ChoiceControl
2222
before(function () {
2323
$_SERVER['REQUEST_METHOD'] = 'POST';
2424
$_POST = $_FILES = [];
25+
$_COOKIE[Nette\Http\Helpers::STRICT_COOKIE_NAME] = '1';
2526
});
2627

2728

0 commit comments

Comments
 (0)