-
-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Feature Request] Support trusted domains for SSR fetch with credentials #4750
Comments
I'm in a similar boat where I have a SvelteKit app at This doesn't seem like an edge case scenario as I would think there are many cases were you may need different frontend apps fetching data from one API server. |
Would this be fixed by #5195? |
Yes, I guess it would. If I understand correctly, that PR no longer automatically binds client cookies to the provided |
Yeah, it makes the whole incoming request available for your consideration. Actually the entire event, so you could even examine "locals" in case you set anything via hooks. |
Hey, i had created an issue related to this one today and it was marked as a duplicate I'm confused as to how is it a duplicate? Shouldn't It's pretty standard to use |
It's not about whether people consider it a subdomain or not, As Even if the cookie is set to the domain itself, this information is not forwarded to SSR, hence SvelteKit takes the most conservative option of checking whether there is a strict domain hierarchy to be sure. It can't differentiate between a domain cookie and a This issue is seeking to provide a way to configure SvelteKit to be able to tell it "hey, |
Ah yes, makes sense. Thanks a lot for clearing it out. Appreciate it. |
Describe the problem
TLDR: SRR fetching during data loading will not forward cookies to the API, if the API is not on a subdomain relative to SSR, with no reasonable option to override this behaviour. This is a delicate problem, as one small misconfiguration and the SSR server may accidentally forward client credentials to an unknown third party, effectively leaking their session key/token.
Currently, SSR fetch will only pass through the
cookie
header if the destination hostname has a suffix matching the SSR application's hostnames, these lines are responsible: This may be partially related to #1777.kit/packages/kit/src/runtime/server/page/load_node.js
Lines 230 to 247 in e3e9373
I imagine that the main issue is that the client does not share domain/SameSite cookie information with the server, only the key/value payload itself, therefore SvelteKit not able to determine whether the cookie is allowed to be shared with the third party, even if it's on the same root domain. The only way to be sure is by checking if the fetch URL is on a subdomain of the received request, only then will the cookie's domain overlap with absolute certainty.
I noticed this when moving from a localhost environment to production, everything broke. Client-side data loading would work correctly, SSR data loading would be unauthenticated, creating confusing state conflicts and many hours of debugging... Someone else had the same experience a year ago.
I understand the rationale behind this, cookies and sessions are hard to keep secure at the best of times, but here the SSR behaviour diverges from the client data-loading behaviour. It's also a very difficult problem to solve, as there is no way to override this behaviour to the best of my knowledge.
Describe the proposed solution
Add an extra fetch parameter or credentials enum value to allow the credentials to be transmitted to the URL, such as
credentials: "force"
. This would effectively be a way to tell SvelteKit/fetch hey, I can vouch for this request, you can send the credentials as well. I'm not sure ifnode-fetch
would allow this, but I don't see why it shouldn't, as long as SvelteKit replaces the key withcredentials: "include"
and adds copies over the cookie header.In my case, the SSR code is responsible for constructing the fetch URL from an environmental variable and a path anyway, seeing as it runs in a trusted environment, I would expect it to behave more like a reverse proxy than a browser fetch API with preflight requests and CORS checks (even though the API is already set up for CORS correctly, seeing as client-side fetch has no problem). I think adequate warning in the data-loading fetch documentation should be enough to inform users of the danger of leaking private cookies if the destination URL is not verified before calling
fetch
.The above would likely pollute the fetch specification and types, a softer alternative would be to add a SvelteKit configuration option to effectively trust a certain domain (or array of domains), allowing for credentials to be forwarded as long as credentials is set to
include
, or at least notomit
, a so-called safelist of API domains.Alternatives considered
The getSession() hook has access to the client request, including headers, making it possible to extract the client cookie manually. This can be used to populate
$session
on every SSR request, similar tosession_start()
in PHP. Data loading is more suitable for injecting relevant data and is also able to hit the API directly from the client to avoid an extra round trip. This is an adequate solution for a small number of use cases, but comes at a relatively high cost when the user is using client-side routing, especially if Vercel limits serverless functions to a single region for the free tier. Computing on the edge solves this only partially.Always using SvelteKit as the root domain, with the API on a subdomain. This is not always possible, for example, my university outright does not allow a subdomain depth of two or more, hence why I had to resort to...
... disable SSR data fetching seems to be the only viable solution, it's the only way to get consistent results, by letting the client fetch data dynamically and letting the browser enforce cookie policies correctly. This comes with the big downside of not having proper SSR, which goes against what SvelteKit is trying to achieve (a.k.a. Rich Harris' coined Transitional Apps term). For example, accessing Vercel without JS enabled will load the page, user-specific content, such as the Sign In button, is only faded in once client JS has run and determined the authentication state. It also complicates the client-side state to prevent subsequent flashes on navigation once the auth state is determined.
The cookie could be smuggled in another header, and forwarded on by SSR to the API that is configured to recognise/accept it, a so-called
X-Forwarded-Cookie
. But... what's the point? It also requires JS and HTTP-only to be disabled.Importance
would make my life easier
Additional Information
No response
The text was updated successfully, but these errors were encountered: