Attack vector arising from naive developer use of the `+layout.server.js` tree
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 20.8k
- Forks
- 2.3k
- Avg merge
- 1d 16h
- Merged PRs (30d)
- 156
Description
Describe the bug
tldr;
- The existence of the
+layout.server.jstree will lead folks to put logic there rather than in+page.server.js. - Because SvelteKit decides on the client what to fetch from the tree, there are edge cases where important (e.g., authorization) logic in
+layout.server.jsis skipped. - This may seem a contrived edge case, but it is an attack vector that needs to be addressed through documentation.
Consider the following case. (Repo link below)
src
└── routes
└── launch-codes
├── +layout.server.js
├── +page.server.js
└── +page.svelte
Let's say I naively (but I think quite naturally) do the following things:
- I place authentication/authorization logic in the
+layout.server.jsfile. Perhaps I plan to elaborate this section of the site withlaunch-codes/[id]. - Meanwhile, I use
+page.server.jsto fetch a paged list of codes from the database.
Essentially I have separated the concerns of authorization and data collection.
Now this is totally secure as long as my user remains signed in. But let's say the following happens:
- The user goes to
/launch-codes. This first page view runs the authorization logic in+layout.server.ts. - They are signed out, say on another tab, or because the cookie expires, or just by deleting the cookie in the console.
- In the original tab, now signed out, they go to
/launch-codes?page=2. The authorization logic in+layout.server.tsis skipped, and the signed out user is shown the launch codes.
I don't think there's a way to reliably fix this in the framework. The client side router decides what to fetch, and that AFAICT will always be manipulable. The only way to "fix" it is by documentation.
(Or we could get rid of the layout data tree notion entirely. Not a bad option, IMO, but a separate losing argument.)
I know all this may seem contrived, but:
- It's not that far-fetched for a developer to assume that separating authorization concerns is partly what
+layout.server.jsis for. - It's not that far-fetched to assume that some apps may require quick cookie expiration. Think your bank.
- It exists. It's an attack vector.
Reproduction
Reproduction here, as minimal as I could make it: https://github.com/cdcarson/yellow-submarine.git
git clone https://github.com/cdcarson/yellow-submarine.git
cd yellow-submarine
npm i
npm run dev
- Go to http://127.0.0.1:5173/launch-codes
- Assuming you are not signed in, you'll be redirected to a sign in page, and redirected back after clicking the button
- Navigate through the paginated list
- In the tab's console, delete the
signedIncookie. (I.e. the cookie has expired or you've been signed out on another tab.) - Without refreshing the page, click to another page in the list. You will be shown that page, rather than being redirected to
/sign-in
I made a separate route with a "non-naive" implementation, getting rid of layout.server.js and doing the authorization in +page.server.ts.
- Go to http://127.0.0.1:5173/launch-codes-fixed
- Replicate the steps above. This time, after deleting the cookie, subsequent navigations through the list at
/launch-codes-fixedwill be redirected to/sign-in
Logs
No response
System Info
System:
OS: macOS 12.4
CPU: (8) arm64 Apple M1
Memory: 70.06 MB / 8.00 GB
Shell: 5.8.1 - /bin/zsh
Binaries:
Node: 16.13.2 - ~/.nvm/versions/node/v16.13.2/bin/node
npm: 8.1.2 - ~/.nvm/versions/node/v16.13.2/bin/npm
Browsers:
Chrome: 104.0.5112.101
Safari: 15.5
npmPackages:
@sveltejs/adapter-auto: next => 1.0.0-next.66
@sveltejs/kit: next => 1.0.0-next.442
svelte: ^3.44.0 => 3.49.0
vite: ^3.0.4 => 3.0.9
Severity
serious, but I can work around it
Additional Information
No response
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Clone the linked yellow-submarine reproduction and follow the launch-codes steps, comparing +layout.server.js with the non-naive launch-codes-fixed route and its +page.server.ts authorization. Review the SvelteKit documentation covering server layouts, page loads, and navigation, then document the safe authorization guidance and verify it against the reproduction steps.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- authentication, documentation, security
- Issue type
- Documentation
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100