Skip to content

Commit fa74106

Browse files
authored
fix(goto): skip cookies from headers (#642)
Cookies are parsed and set via `page.setCookie`, so they have to be excluded from being set via `page.setExtraHTTPHeaders`.
1 parent 2668c86 commit fa74106

File tree

2 files changed

+99
-7
lines changed

2 files changed

+99
-7
lines changed

packages/goto/src/index.js

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,8 @@ module.exports = ({ defaultDevice = 'Macbook Pro 13', timeout: globalTimeout, ..
326326
const headersKeys = Object.keys(headers)
327327

328328
if (headersKeys.length > 0) {
329+
const { cookie, ...headersWithoutCookie } = headers
330+
329331
if (headers.cookie) {
330332
const cookies = parseCookies(url, headers.cookie)
331333
prePromises.push(
@@ -337,6 +339,9 @@ module.exports = ({ defaultDevice = 'Macbook Pro 13', timeout: globalTimeout, ..
337339
)
338340
}
339341

342+
const extraHTTPHeaders = headers.cookie ? headersWithoutCookie : headers
343+
const extraHTTPHeadersKeys = Object.keys(extraHTTPHeaders)
344+
340345
if (headers['user-agent']) {
341346
prePromises.push(
342347
run({
@@ -347,13 +352,15 @@ module.exports = ({ defaultDevice = 'Macbook Pro 13', timeout: globalTimeout, ..
347352
)
348353
}
349354

350-
prePromises.push(
351-
run({
352-
fn: page.setExtraHTTPHeaders(headers),
353-
timeout: actionTimeout,
354-
debug: { headers: headersKeys }
355-
})
356-
)
355+
if (extraHTTPHeadersKeys.length > 0) {
356+
prePromises.push(
357+
run({
358+
fn: page.setExtraHTTPHeaders(extraHTTPHeaders),
359+
timeout: actionTimeout,
360+
debug: { headers: extraHTTPHeadersKeys }
361+
})
362+
)
363+
}
357364
}
358365

359366
if (timezone) {

packages/goto/test/unit/headers/index.js

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,3 +76,88 @@ test('set `cookie` header', async t => {
7676
t.is(body.headers.cookie, 'yummy_cookie=choco; tasty_cookie=strawberry')
7777
t.is(cookies.length, 2)
7878
})
79+
80+
test('does not forward cookie through extra headers', async t => {
81+
const browserless = await getBrowserContext(t)
82+
const url = await getUrl(t)
83+
let extraHTTPHeaders
84+
85+
const run = browserless.withPage((page, goto) => async () => {
86+
const originalSetExtraHTTPHeaders = page.setExtraHTTPHeaders.bind(page)
87+
page.setExtraHTTPHeaders = headers => {
88+
extraHTTPHeaders = headers
89+
return originalSetExtraHTTPHeaders(headers)
90+
}
91+
92+
const result = await goto(page, {
93+
url,
94+
headers: {
95+
'x-foo': 'bar',
96+
cookie: 'yummy_cookie=choco'
97+
}
98+
})
99+
100+
const cookies = await page.cookies(url)
101+
return { result, cookies }
102+
})
103+
104+
const { cookies } = await run()
105+
106+
t.truthy(extraHTTPHeaders)
107+
t.false(Object.prototype.hasOwnProperty.call(extraHTTPHeaders, 'cookie'))
108+
t.true(cookies.some(({ name, value }) => name === 'yummy_cookie' && value === 'choco'))
109+
})
110+
111+
test('cookies are not sent to subrequests via extra headers', async t => {
112+
const browserless = await getBrowserContext(t)
113+
let subrequestHeaders
114+
115+
const subrequestUrl = (
116+
await runServer(t, ({ req, res }) => {
117+
if (req.method === 'OPTIONS') {
118+
res.setHeader('access-control-allow-origin', '*')
119+
res.setHeader('access-control-allow-methods', 'GET,POST,OPTIONS')
120+
res.setHeader('access-control-allow-headers', 'x-foo')
121+
res.statusCode = 204
122+
return res.end()
123+
}
124+
125+
subrequestHeaders = req.headers
126+
res.setHeader('access-control-allow-origin', '*')
127+
res.setHeader('content-type', 'application/json')
128+
res.end(JSON.stringify({ ok: true }))
129+
})
130+
).replace('127.0.0.1', 'localhost')
131+
132+
const url = await runServer(t, ({ res }) => {
133+
res.setHeader('content-type', 'text/html')
134+
res.end(`
135+
<script>
136+
fetch('${subrequestUrl}').finally(() => {
137+
window.__subrequest_complete = true
138+
})
139+
</script>
140+
`)
141+
})
142+
143+
const run = browserless.withPage((page, goto) => async () => {
144+
await goto(page, {
145+
url,
146+
waitForFunction: () => window.__subrequest_complete === true,
147+
headers: {
148+
'x-foo': 'bar',
149+
cookie: 'secret_token=top_secret'
150+
}
151+
})
152+
153+
const cookies = await page.cookies(url)
154+
return { cookies }
155+
})
156+
157+
const { cookies } = await run()
158+
159+
t.truthy(subrequestHeaders)
160+
t.is(subrequestHeaders['x-foo'], 'bar')
161+
t.falsy(subrequestHeaders.cookie)
162+
t.true(cookies.some(({ name, value }) => name === 'secret_token' && value === 'top_secret'))
163+
})

0 commit comments

Comments
 (0)