Skip to content

Commit 31c09f2

Browse files
committed
removed samesite check using cookie (BC break)
1 parent f5ea7e4 commit 31c09f2

6 files changed

Lines changed: 4 additions & 127 deletions

File tree

src/Bridges/HttpDI/HttpExtension.php

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ public function getConfigSchema(): Nette\Schema\Schema
5353
'cookiePath' => Expect::string()->dynamic(),
5454
'cookieDomain' => Expect::string()->dynamic(),
5555
'cookieSecure' => Expect::anyOf('auto', null, true, false)->firstIsDefault()->dynamic(), // Whether the cookie is available only through HTTPS
56-
'disableNetteCookie' => Expect::bool(false), // disables cookie use by Nette
56+
'disableNetteCookie' => Expect::bool(false)->deprecated(),
5757
]);
5858
}
5959

@@ -150,13 +150,6 @@ private function sendHeaders(): void
150150
$this->initialization->addBody('$response->setHeader(?, ?);', [$key, $value]);
151151
}
152152
}
153-
154-
if (!$config->disableNetteCookie) {
155-
$this->initialization->addBody(
156-
'Nette\Http\Helpers::initCookie($this->getService(?), $response);',
157-
[$this->prefix('request')],
158-
);
159-
}
160153
}
161154

162155

src/Http/Helpers.php

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,6 @@ final class Helpers
1919
{
2020
use Nette\StaticClass;
2121

22-
/** @internal */
23-
public const StrictCookieName = '_nss';
24-
2522

2623
/**
2724
* Formats a date and time in the HTTP date format (RFC 7231), e.g. 'Mon, 23 Jan 1978 10:00:00 GMT'.
@@ -107,16 +104,4 @@ public static function ipMatch(string $ip, string $mask): bool
107104
{
108105
return IPAddress::tryFrom($ip)?->isInRange($mask) ?? false;
109106
}
110-
111-
112-
/**
113-
* Sends the SameSite=Strict cookie used as a fallback for detecting same-site requests
114-
* in browsers that don't support the Sec-Fetch-Site header (Safari < 16.4).
115-
*/
116-
public static function initCookie(IRequest $request, IResponse $response): void
117-
{
118-
if ($request->getHeader('Sec-Fetch-Site') === null) {
119-
$response->setCookie(self::StrictCookieName, '1', null, '/', sameSite: SameSite::Strict);
120-
}
121-
}
122107
}

src/Http/Request.php

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
namespace Nette\Http;
99

1010
use Nette;
11-
use function array_change_key_case, array_filter, base64_decode, count, explode, func_num_args, in_array, is_array, preg_match, strcasecmp, strlen, strtr;
11+
use function array_change_key_case, base64_decode, count, explode, func_num_args, in_array, is_array, preg_match, strcasecmp, strlen, strtr;
1212

1313

1414
/**
@@ -242,7 +242,6 @@ public function isSameSite(): bool
242242

243243
/**
244244
* Checks whether the request matches the given Sec-Fetch-Site, Sec-Fetch-Dest and Sec-Fetch-User values.
245-
* Falls back to the SameSite=Strict cookie in browsers without Sec-Fetch (Safari < 16.4)
246245
* @param FetchSite|list<FetchSite> $site
247246
* @param FetchDest|list<FetchDest>|null $dest
248247
*/
@@ -252,20 +251,12 @@ public function isFrom(
252251
?bool $user = null,
253252
): bool
254253
{
255-
$siteHeader = $this->headers['sec-fetch-site'] ?? null;
254+
$actualSite = FetchSite::tryFrom($this->headers['sec-fetch-site'] ?? '');
256255
$actualDest = FetchDest::tryFrom($this->headers['sec-fetch-dest'] ?? '');
257256
$actualUser = ($this->headers['sec-fetch-user'] ?? null) === '?1';
258257
$site = is_array($site) ? $site : [$site];
259258
$dest = $dest === null || is_array($dest) ? $dest : [$dest];
260259

261-
if ($siteHeader === null) { // fallback for browsers without Sec-Fetch (Safari < 16.4)
262-
return $dest === null
263-
&& $user === null
264-
&& isset($this->cookies[Helpers::StrictCookieName])
265-
&& array_filter($site, fn(FetchSite $s) => $s !== FetchSite::CrossSite) !== [];
266-
}
267-
268-
$actualSite = FetchSite::tryFrom($siteHeader);
269260
return $actualSite !== null
270261
&& in_array($actualSite, $site, strict: true)
271262
&& ($dest === null || ($actualDest !== null && in_array($actualDest, $dest, strict: true)))

tests/Http.DI/HttpExtension.sameSiteProtection.disabled.phpt

Lines changed: 0 additions & 28 deletions
This file was deleted.

tests/Http.DI/HttpExtension.sameSiteProtection.phpt

Lines changed: 0 additions & 27 deletions
This file was deleted.

tests/Http/Request.isFrom.phpt

Lines changed: 1 addition & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -80,46 +80,9 @@ test('unknown header value matches nothing', function () {
8080
});
8181

8282

83-
test('no header, no cookie returns false', function () {
83+
test('no Sec-Fetch-Site returns false', function () {
8484
$request = new Http\Request(new Http\UrlScript);
8585

8686
Assert::false($request->isFrom(FetchSite::SameOrigin));
8787
Assert::false($request->isFrom(FetchSite::CrossSite));
8888
});
89-
90-
91-
test('cookie fallback proves only "not cross-site"', function () {
92-
$request = new Http\Request(new Http\UrlScript, cookies: [
93-
Http\Helpers::StrictCookieName => '1',
94-
]);
95-
96-
Assert::true($request->isFrom(FetchSite::SameOrigin));
97-
Assert::true($request->isFrom(FetchSite::SameSite));
98-
Assert::true($request->isFrom(FetchSite::None));
99-
Assert::true($request->isFrom([FetchSite::SameOrigin, FetchSite::CrossSite]));
100-
Assert::false($request->isFrom(FetchSite::CrossSite));
101-
});
102-
103-
104-
test('cookie fallback fails closed for dest & user', function () {
105-
$request = new Http\Request(new Http\UrlScript, cookies: [
106-
Http\Helpers::StrictCookieName => '1',
107-
]);
108-
109-
// dest/user can't be proven by the cookie alone, so a stricter check must not pass
110-
Assert::false($request->isFrom(FetchSite::SameOrigin, FetchDest::Document));
111-
Assert::false($request->isFrom(FetchSite::SameOrigin, user: true));
112-
Assert::false($request->isFrom(FetchSite::SameOrigin, user: false));
113-
});
114-
115-
116-
test('cookie fallback not used when Sec-Fetch-Site present', function () {
117-
$request = new Http\Request(new Http\UrlScript, cookies: [
118-
Http\Helpers::StrictCookieName => '1',
119-
], headers: [
120-
'Sec-Fetch-Site' => 'cross-site',
121-
]);
122-
123-
Assert::false($request->isFrom(FetchSite::SameOrigin));
124-
Assert::true($request->isFrom(FetchSite::CrossSite));
125-
});

0 commit comments

Comments
 (0)