Skip to content

Commit 9db65f0

Browse files
authored
fix(http): don't cache csrf tokens in views (#1412)
1 parent daee10d commit 9db65f0

File tree

4 files changed

+45
-31
lines changed

4 files changed

+45
-31
lines changed

packages/http/src/Session/CsrfTokenComponent.php

Lines changed: 0 additions & 29 deletions
This file was deleted.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
use Tempest\Http\Session\Session;
4+
5+
use function Tempest\get;
6+
7+
$name = Session::CSRF_TOKEN_KEY;
8+
$token = get(Session::class)->token;
9+
?>
10+
11+
<input type="hidden" name="{{ $name }}" value="{{ $token }}" />

tests/Integration/FrameworkIntegrationTestCase.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,4 +219,14 @@ protected function skipWindows(string $reason): void
219219

220220
$this->markTestSkipped($reason);
221221
}
222+
223+
/**
224+
* @template TClassName of object
225+
* @param class-string<TClassName> $className
226+
* @return null|TClassName
227+
*/
228+
protected function get(string $className): ?object
229+
{
230+
return $this->container->get($className);
231+
}
222232
}

tests/Integration/Http/CsrfTest.php

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use Tempest\Http\Session\CsrfTokenDidNotMatch;
1212
use Tempest\Http\Session\Session;
1313
use Tempest\Http\Session\VerifyCsrfMiddleware;
14+
use Tempest\View\ViewCache;
1415
use Tests\Tempest\Integration\FrameworkIntegrationTestCase;
1516

1617
final class CsrfTest extends FrameworkIntegrationTestCase
@@ -97,13 +98,34 @@ public function test_matches_from_header(): void
9798

9899
public function test_csrf_component(): void
99100
{
101+
$session = $this->container->get(Session::class);
102+
$session->set(Session::CSRF_TOKEN_KEY, 'test');
103+
100104
$rendered = $this->render(<<<HTML
101105
<x-csrf-token />
102106
HTML);
103107

108+
$this->assertSame(
109+
'<input type="hidden" name="_csrf_token" value="test">',
110+
$rendered,
111+
);
112+
}
113+
114+
public function test_csrf_with_cached_view(): void
115+
{
116+
$this->get(ViewCache::class)->enabled = true;
117+
118+
$oldVersion = $this->render(<<<HTML
119+
<x-csrf-token />
120+
HTML);
121+
104122
$session = $this->container->get(Session::class);
123+
$session->destroy();
124+
125+
$newVersion = $this->render(<<<HTML
126+
<x-csrf-token />
127+
HTML);
105128

106-
$this->assertStringMatchesFormat('<input type="hidden" name="_csrf_token" value="%s">', $rendered);
107-
$this->assertStringContainsString($session->token, $rendered);
129+
$this->assertNotSame($oldVersion, $newVersion);
108130
}
109131
}

0 commit comments

Comments
 (0)