-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Improve JSON payload handling #4128
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
Changes from all commits
b1cbc7a
ff20307
8abd031
ab6de2a
dcce7c3
d26fa69
b2fd95e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'@sveltejs/kit': patch | ||
--- | ||
|
||
Fix XSS vulnerability on SSR pages with fetched data on `load()` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,22 @@ | ||
import { JSONValue, NormalizedLoadOutput, SSRNode } from 'types'; | ||
import { JSONValue, NormalizedLoadOutput, ResponseHeaders, SSRNode } from 'types'; | ||
|
||
export type Fetched = { | ||
url: string; | ||
body?: string | null; | ||
response: { | ||
status: number; | ||
statusText: string; | ||
headers: ResponseHeaders; | ||
body: string; | ||
}; | ||
}; | ||
|
||
export type Loaded = { | ||
node: SSRNode; | ||
props: JSONValue | undefined; | ||
loaded: NormalizedLoadOutput; | ||
stuff: Record<string, any>; | ||
fetched: Array<{ url: string; body: string; json: string }>; | ||
fetched: Fetched[]; | ||
set_cookie_headers: string[]; | ||
uses_credentials: boolean; | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,35 @@ | ||
import { suite } from 'uvu'; | ||
import * as assert from 'uvu/assert'; | ||
import { escape_html_attr } from './escape.js'; | ||
import { render_json_payload_script, escape_html_attr } from './escape.js'; | ||
|
||
const json = suite('render_json_payload_script'); | ||
|
||
json('escapes slashes', () => { | ||
assert.equal( | ||
render_json_payload_script({ type: 'props' }, { unsafe: '</script><script>alert("xss")' }), | ||
'<script type="application/json" sveltekit:data-type="props">' + | ||
'{"unsafe":"\\u003C/script>\\u003Cscript>alert(\\"xss\\")"}' + | ||
'</script>' | ||
); | ||
}); | ||
|
||
json('escapes exclamation marks', () => { | ||
assert.equal( | ||
render_json_payload_script({ type: 'props' }, { '<!--</script>...-->alert("xss")': 'unsafe' }), | ||
'<script type="application/json" sveltekit:data-type="props">' + | ||
'{"\\u003C!--\\u003C/script>...-->alert(\\"xss\\")":"unsafe"}' + | ||
'</script>' | ||
); | ||
}); | ||
|
||
json('escapes the attribute values', () => { | ||
const raw = 'an "attr" & a \ud800'; | ||
const escaped = 'an "attr" & a �'; | ||
assert.equal( | ||
render_json_payload_script({ type: 'data', url: raw }, {}), | ||
`<script type="application/json" sveltekit:data-type="data" sveltekit:data-url="${escaped}">{}</script>` | ||
); | ||
}); | ||
|
||
const attr = suite('escape_html_attr'); | ||
|
||
|
@@ -21,4 +50,5 @@ attr('escapes invalid surrogates', () => { | |
assert.equal(escape_html_attr('\ud800\ud800\udc00\udc00'), '"�\ud800\udc00�"'); | ||
}); | ||
|
||
json.run(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I saw @Rich-Harris comment on a recent PR that it didn't need to create a test suite. The test setup has changed a lot and I'm not sure under which circumstances a test suite is needed and when it is not needed. Flagging this for his attention and my education 😄 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I thought suites were just informational groups to help test navigation—without them, all tests go into a single anonymous suite. I'll remove them if that causes issues! |
||
attr.run(); |
Uh oh!
There was an error while loading. Please reload this page.