-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Description
Describe the bug
kit/packages/kit/src/runtime/server/page/load_node.js
Lines 100 to 103 in 5cea0c2
| if (/^[a-zA-Z]+:/.test(url)) { | |
| // external fetch | |
| const request = new Request(url, /** @type {RequestInit} */ (opts)); | |
| response = await options.hooks.serverFetch.call(null, request); |
Currently, all absolute fetch requests are treated as cross-origin, and cookies are not passed through. This does not adequately cover the three main cases of same-origin sites where cookies are shared:
- Different port on the same domain, e.g.
localhost:3000andlocalhost:5000 - Subdomains, e.g.
api.domain.comanddomain.com - The same domain and port, but specified as an absolute path to satisfy some library (e.g. Apollo, which sucks)
However, this is not a trivial fix:
- Passing in cookies for all external requests would lead to indiscriminately sending cookies to cross-origin domains, which is wasted bandwidth at best and a security violation at worst.
- Browsers do not send the domain associated with cookies. A SvelteKit server hosted at
sub.domain.comcan receive cookies fromdomain.comORsub.domain.comand cannot distinguish the two.
The lack of domain information presents various issues and limitations for potential solutions.
[Loose] If we assume that received cookies all belong to the second-level domain:
- We must identify what a "second-level domain" actually is (e.g.
domain.co.ukexists, so we cannot blindly assume the level of the domain based on the number of separators) - This is a security issue for subdomains that are shared with others, as is common in shared hosting (e.g. vercel, github pages, js.org) as it can happily send all
vercel.appcookies tomalicious.vercel.app - This assumption is invalid for any pages hosted on direct IP addresses (eg. https://1.1.1.1 from Cloudflare)
[Strict] If we pick the strictest domain and assume received cookies belong to the current domain of the application:
- A SvelteKit app hosted at
sub.domain.comwould have to assumedomain.comcookies assub.domain.comcookies, and soapi.domain.comwould not be eligible to receive the cookies from server-side fetch using this algorithm, despite the fact that they would normally be passed by the browser clientside. - The above behavior would require extensive documentation, as it would be a difference between the client and the server fetch.
The above also assumes we can adequately identify the current host. The Host HTTP header can be manipulated by the client, which seems questionable. A configurable setting may lead unaware devs to emulate the loose mode to "make things work" and turn the feature into a footgun.
To Reproduce
https://github.com/GrygrFlzr/sk-cookie-issue
Expected behavior
Cookies passed through to the API endpoint for the "Same Domain and Port" and "Same Domain, Different Port" cases.
Information about your SvelteKit Installation:
Diagnostics
System:
OS: Windows 10 10.0.22000
CPU: (16) x64 AMD Ryzen 7 3700X 8-Core Processor
Memory: 15.96 GB / 31.93 GB
Binaries:
Node: 14.16.0 - C:\program files\nodejs\node.EXE
Yarn: 1.22.10 - ~\AppData\Roaming\npm\yarn.CMD
npm: 6.14.13 - C:\program files\nodejs\npm.CMD
Browsers:
Chrome: 91.0.4472.124
Edge: Spartan (44.22000.1.0), Chromium (91.0.864.59)
Internet Explorer: 11.0.22000.1
npmPackages:
@sveltejs/kit: next => 1.0.0-next.119
svelte: ^3.34.0 => 3.38.3
Severity
Depends:
- Annoyance for situations where proxying the API in SvelteKit is possible - it's an extra network trip.
- Blocking for situations involving third party libraries.