Skip to content

Commit 45ec63d

Browse files
authored
fix: Remove isAUTFrame qualification from cross origin cookie check (#22963)
1 parent 964ac37 commit 45ec63d

File tree

4 files changed

+166
-137
lines changed

4 files changed

+166
-137
lines changed

packages/driver/cypress/e2e/e2e/origin/commands/cookies.cy.ts

Lines changed: 154 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -1,176 +1,200 @@
11
import { findCrossOriginLogs } from '../../../../support/utils'
22

3-
context('cy.origin cookies', () => {
4-
beforeEach(() => {
5-
cy.visit('/fixtures/primary-origin.html')
6-
cy.get('a[data-cy="cross-origin-secondary-link"]').click()
7-
})
3+
describe('cy.origin cookies', () => {
4+
context('client side', () => {
5+
beforeEach(() => {
6+
cy.visit('/fixtures/primary-origin.html')
7+
cy.get('a[data-cy="cross-origin-secondary-link"]').click()
8+
})
89

9-
it('.getCookie(), .getCookies(), and .setCookie()', () => {
10-
cy.origin('http://foobar.com:3500', () => {
11-
cy.getCookies().should('be.empty')
10+
it('.getCookie(), .getCookies(), and .setCookie()', () => {
11+
cy.origin('http://foobar.com:3500', () => {
12+
cy.getCookies().should('be.empty')
1213

13-
cy.setCookie('foo', 'bar')
14+
cy.setCookie('foo', 'bar')
1415

15-
cy.getCookie('foo').should('have.property', 'value', 'bar')
16-
cy.getCookies().should('have.length', 1)
16+
cy.getCookie('foo').should('have.property', 'value', 'bar')
17+
cy.getCookies().should('have.length', 1)
18+
})
1719
})
18-
})
1920

20-
it('.clearCookie()', () => {
21-
cy.origin('http://foobar.com:3500', () => {
22-
cy.setCookie('foo', 'bar')
23-
cy.getCookie('foo').should('not.be.null')
24-
cy.clearCookie('foo')
25-
cy.getCookie('foo').should('be.null')
21+
it('.clearCookie()', () => {
22+
cy.origin('http://foobar.com:3500', () => {
23+
cy.setCookie('foo', 'bar')
24+
cy.getCookie('foo').should('not.be.null')
25+
cy.clearCookie('foo')
26+
cy.getCookie('foo').should('be.null')
27+
})
2628
})
27-
})
2829

29-
it('.clearCookies()', () => {
30-
cy.origin('http://foobar.com:3500', () => {
31-
cy.setCookie('foo', 'bar')
32-
cy.setCookie('faz', 'baz')
30+
it('.clearCookies()', () => {
31+
cy.origin('http://foobar.com:3500', () => {
32+
cy.setCookie('foo', 'bar')
33+
cy.setCookie('faz', 'baz')
3334

34-
cy.getCookies().should('have.length', 2)
35-
cy.clearCookies()
36-
cy.getCookies().should('be.empty')
35+
cy.getCookies().should('have.length', 2)
36+
cy.clearCookies()
37+
cy.getCookies().should('be.empty')
38+
})
3739
})
38-
})
3940

40-
context('#consoleProps', () => {
41-
const { _ } = Cypress
42-
let logs: Map<string, any>
41+
context('#consoleProps', () => {
42+
const { _ } = Cypress
43+
let logs: Map<string, any>
4344

44-
beforeEach(() => {
45-
logs = new Map()
45+
beforeEach(() => {
46+
logs = new Map()
4647

47-
cy.on('log:changed', (attrs, log) => {
48-
logs.set(attrs.id, log)
48+
cy.on('log:changed', (attrs, log) => {
49+
logs.set(attrs.id, log)
50+
})
4951
})
50-
})
5152

52-
it('.getCookie()', () => {
53-
cy.origin('http://foobar.com:3500', () => {
54-
cy.getCookies().should('be.empty')
55-
cy.setCookie('foo', 'bar')
56-
cy.getCookie('foo')
57-
})
53+
it('.getCookie()', () => {
54+
cy.origin('http://foobar.com:3500', () => {
55+
cy.getCookies().should('be.empty')
56+
cy.setCookie('foo', 'bar')
57+
cy.getCookie('foo')
58+
})
5859

59-
cy.shouldWithTimeout(() => {
60-
const { consoleProps } = findCrossOriginLogs('getCookie', logs, 'foobar.com')
61-
62-
expect(consoleProps.Command).to.equal('getCookie')
63-
expect(consoleProps.Yielded).to.have.property('domain').that.includes('foobar.com')
64-
expect(consoleProps.Yielded).to.have.property('expiry').that.is.a('number')
65-
expect(consoleProps.Yielded).to.have.property('httpOnly').that.equals(false)
66-
expect(consoleProps.Yielded).to.have.property('secure').that.equals(false)
67-
expect(consoleProps.Yielded).to.have.property('name').that.equals('foo')
68-
expect(consoleProps.Yielded).to.have.property('value').that.equals('bar')
69-
expect(consoleProps.Yielded).to.have.property('path').that.is.a('string')
60+
cy.shouldWithTimeout(() => {
61+
const { consoleProps } = findCrossOriginLogs('getCookie', logs, 'foobar.com')
62+
63+
expect(consoleProps.Command).to.equal('getCookie')
64+
expect(consoleProps.Yielded).to.have.property('domain').that.includes('foobar.com')
65+
expect(consoleProps.Yielded).to.have.property('expiry').that.is.a('number')
66+
expect(consoleProps.Yielded).to.have.property('httpOnly').that.equals(false)
67+
expect(consoleProps.Yielded).to.have.property('secure').that.equals(false)
68+
expect(consoleProps.Yielded).to.have.property('name').that.equals('foo')
69+
expect(consoleProps.Yielded).to.have.property('value').that.equals('bar')
70+
expect(consoleProps.Yielded).to.have.property('path').that.is.a('string')
71+
})
7072
})
71-
})
7273

73-
it('.getCookies()', () => {
74-
cy.origin('http://foobar.com:3500', () => {
75-
cy.getCookies().should('be.empty')
74+
it('.getCookies()', () => {
75+
cy.origin('http://foobar.com:3500', () => {
76+
cy.getCookies().should('be.empty')
7677

77-
cy.setCookie('foo', 'bar')
78-
cy.getCookies()
79-
})
78+
cy.setCookie('foo', 'bar')
79+
cy.getCookies()
80+
})
8081

81-
cy.shouldWithTimeout(() => {
82+
cy.shouldWithTimeout(() => {
8283
// get the last 'getCookies' command, which is the one we care about for this test
83-
const allGetCookieLogs = findCrossOriginLogs('getCookies', logs, 'foobar.com')
84+
const allGetCookieLogs = findCrossOriginLogs('getCookies', logs, 'foobar.com')
8485

85-
const { consoleProps } = allGetCookieLogs.pop() as any
86+
const { consoleProps } = allGetCookieLogs.pop() as any
8687

87-
expect(consoleProps.Command).to.equal('getCookies')
88-
expect(consoleProps['Num Cookies']).to.equal(1)
88+
expect(consoleProps.Command).to.equal('getCookies')
89+
expect(consoleProps['Num Cookies']).to.equal(1)
8990

90-
// can't exactly assert on length() as this is a array proxy object
91-
expect(consoleProps.Yielded.length).to.equal(1)
92-
expect(consoleProps.Yielded[0]).to.have.property('expiry').that.is.a('number')
93-
expect(consoleProps.Yielded[0]).to.have.property('httpOnly').that.equals(false)
94-
expect(consoleProps.Yielded[0]).to.have.property('secure').that.equals(false)
95-
expect(consoleProps.Yielded[0]).to.have.property('name').that.equals('foo')
96-
expect(consoleProps.Yielded[0]).to.have.property('value').that.equals('bar')
97-
expect(consoleProps.Yielded[0]).to.have.property('path').that.is.a('string')
91+
// can't exactly assert on length() as this is a array proxy object
92+
expect(consoleProps.Yielded.length).to.equal(1)
93+
expect(consoleProps.Yielded[0]).to.have.property('expiry').that.is.a('number')
94+
expect(consoleProps.Yielded[0]).to.have.property('httpOnly').that.equals(false)
95+
expect(consoleProps.Yielded[0]).to.have.property('secure').that.equals(false)
96+
expect(consoleProps.Yielded[0]).to.have.property('name').that.equals('foo')
97+
expect(consoleProps.Yielded[0]).to.have.property('value').that.equals('bar')
98+
expect(consoleProps.Yielded[0]).to.have.property('path').that.is.a('string')
99+
})
98100
})
99-
})
100101

101-
it('.setCookie()', () => {
102-
cy.origin('http://foobar.com:3500', () => {
103-
cy.getCookies().should('be.empty')
102+
it('.setCookie()', () => {
103+
cy.origin('http://foobar.com:3500', () => {
104+
cy.getCookies().should('be.empty')
104105

105-
cy.setCookie('foo', 'bar')
106-
})
106+
cy.setCookie('foo', 'bar')
107+
})
107108

108-
cy.shouldWithTimeout(() => {
109-
const { consoleProps } = findCrossOriginLogs('setCookie', logs, 'foobar.com')
110-
111-
expect(consoleProps.Command).to.equal('setCookie')
112-
expect(consoleProps.Yielded).to.have.property('domain').that.includes('foobar.com')
113-
expect(consoleProps.Yielded).to.have.property('expiry').that.is.a('number')
114-
expect(consoleProps.Yielded).to.have.property('httpOnly').that.equals(false)
115-
expect(consoleProps.Yielded).to.have.property('secure').that.equals(false)
116-
expect(consoleProps.Yielded).to.have.property('name').that.equals('foo')
117-
expect(consoleProps.Yielded).to.have.property('value').that.equals('bar')
118-
expect(consoleProps.Yielded).to.have.property('path').that.is.a('string')
109+
cy.shouldWithTimeout(() => {
110+
const { consoleProps } = findCrossOriginLogs('setCookie', logs, 'foobar.com')
111+
112+
expect(consoleProps.Command).to.equal('setCookie')
113+
expect(consoleProps.Yielded).to.have.property('domain').that.includes('foobar.com')
114+
expect(consoleProps.Yielded).to.have.property('expiry').that.is.a('number')
115+
expect(consoleProps.Yielded).to.have.property('httpOnly').that.equals(false)
116+
expect(consoleProps.Yielded).to.have.property('secure').that.equals(false)
117+
expect(consoleProps.Yielded).to.have.property('name').that.equals('foo')
118+
expect(consoleProps.Yielded).to.have.property('value').that.equals('bar')
119+
expect(consoleProps.Yielded).to.have.property('path').that.is.a('string')
120+
})
119121
})
120-
})
121122

122-
it('.clearCookie()', () => {
123-
cy.origin('http://foobar.com:3500', () => {
124-
cy.setCookie('foo', 'bar')
125-
cy.getCookie('foo').should('not.be.null')
126-
cy.clearCookie('foo')
127-
})
123+
it('.clearCookie()', () => {
124+
cy.origin('http://foobar.com:3500', () => {
125+
cy.setCookie('foo', 'bar')
126+
cy.getCookie('foo').should('not.be.null')
127+
cy.clearCookie('foo')
128+
})
128129

129-
cy.shouldWithTimeout(() => {
130-
const { consoleProps } = findCrossOriginLogs('clearCookie', logs, 'foobar.com')
131-
132-
expect(consoleProps.Command).to.equal('clearCookie')
133-
expect(consoleProps.Yielded).to.equal('null')
134-
expect(consoleProps['Cleared Cookie']).to.have.property('domain').that.includes('foobar.com')
135-
expect(consoleProps['Cleared Cookie']).to.have.property('expiry').that.is.a('number')
136-
expect(consoleProps['Cleared Cookie']).to.have.property('httpOnly').that.equals(false)
137-
expect(consoleProps['Cleared Cookie']).to.have.property('secure').that.equals(false)
138-
expect(consoleProps['Cleared Cookie']).to.have.property('name').that.equals('foo')
139-
expect(consoleProps['Cleared Cookie']).to.have.property('value').that.equals('bar')
140-
expect(consoleProps['Cleared Cookie']).to.have.property('path').that.is.a('string')
130+
cy.shouldWithTimeout(() => {
131+
const { consoleProps } = findCrossOriginLogs('clearCookie', logs, 'foobar.com')
132+
133+
expect(consoleProps.Command).to.equal('clearCookie')
134+
expect(consoleProps.Yielded).to.equal('null')
135+
expect(consoleProps['Cleared Cookie']).to.have.property('domain').that.includes('foobar.com')
136+
expect(consoleProps['Cleared Cookie']).to.have.property('expiry').that.is.a('number')
137+
expect(consoleProps['Cleared Cookie']).to.have.property('httpOnly').that.equals(false)
138+
expect(consoleProps['Cleared Cookie']).to.have.property('secure').that.equals(false)
139+
expect(consoleProps['Cleared Cookie']).to.have.property('name').that.equals('foo')
140+
expect(consoleProps['Cleared Cookie']).to.have.property('value').that.equals('bar')
141+
expect(consoleProps['Cleared Cookie']).to.have.property('path').that.is.a('string')
142+
})
141143
})
142-
})
143144

144-
it('.clearCookies()', () => {
145-
cy.origin('http://foobar.com:3500', () => {
146-
cy.setCookie('foo', 'bar')
147-
cy.setCookie('faz', 'baz')
145+
it('.clearCookies()', () => {
146+
cy.origin('http://foobar.com:3500', () => {
147+
cy.setCookie('foo', 'bar')
148+
cy.setCookie('faz', 'baz')
148149

149-
cy.getCookies().should('have.length', 2)
150-
cy.clearCookies()
151-
})
150+
cy.getCookies().should('have.length', 2)
151+
cy.clearCookies()
152+
})
153+
154+
cy.shouldWithTimeout(() => {
155+
const { consoleProps } = findCrossOriginLogs('clearCookies', logs, 'foobar.com')
152156

153-
cy.shouldWithTimeout(() => {
154-
const { consoleProps } = findCrossOriginLogs('clearCookies', logs, 'foobar.com')
157+
expect(consoleProps.Command).to.equal('clearCookies')
158+
expect(consoleProps['Num Cookies']).to.equal(2)
155159

156-
expect(consoleProps.Command).to.equal('clearCookies')
157-
expect(consoleProps['Num Cookies']).to.equal(2)
160+
expect(consoleProps.Yielded).to.equal('null')
158161

159-
expect(consoleProps.Yielded).to.equal('null')
162+
expect(consoleProps['Cleared Cookies'].length).to.equal(2)
160163

161-
expect(consoleProps['Cleared Cookies'].length).to.equal(2)
164+
expect(consoleProps['Cleared Cookies'][0]).to.have.property('name').that.equals('foo')
165+
expect(consoleProps['Cleared Cookies'][0]).to.have.property('value').that.equals('bar')
162166

163-
expect(consoleProps['Cleared Cookies'][0]).to.have.property('name').that.equals('foo')
164-
expect(consoleProps['Cleared Cookies'][0]).to.have.property('value').that.equals('bar')
167+
expect(consoleProps['Cleared Cookies'][1]).to.have.property('name').that.equals('faz')
168+
expect(consoleProps['Cleared Cookies'][1]).to.have.property('value').that.equals('baz')
165169

166-
expect(consoleProps['Cleared Cookies'][1]).to.have.property('name').that.equals('faz')
167-
expect(consoleProps['Cleared Cookies'][1]).to.have.property('value').that.equals('baz')
170+
_.forEach(consoleProps['Cleared Cookies'], (clearedCookie) => {
171+
expect(clearedCookie).to.have.property('httpOnly').that.equals(false)
172+
expect(clearedCookie).to.have.property('secure').that.equals(false)
173+
expect(clearedCookie).to.have.property('path').that.is.a('string')
174+
})
175+
})
176+
})
177+
})
178+
})
179+
180+
context('server side', () => {
181+
it('supports Set-Cookie response header through fetch request', () => {
182+
cy.intercept('/dump-headers').as('headers')
168183

169-
_.forEach(consoleProps['Cleared Cookies'], (clearedCookie) => {
170-
expect(clearedCookie).to.have.property('httpOnly').that.equals(false)
171-
expect(clearedCookie).to.have.property('secure').that.equals(false)
172-
expect(clearedCookie).to.have.property('path').that.is.a('string')
184+
cy.origin('http://www.foobar.com:3500', () => {
185+
cy.visit('/')
186+
cy.window().then((win) => {
187+
return cy.wrap(win.fetch('/set-cookie?cookie=foo=bar;'))
173188
})
189+
190+
cy.window().then((win) => {
191+
win.location.href = 'http://www.foobar.com:3500/dump-headers'
192+
})
193+
194+
cy.wait('@headers')
195+
196+
cy.contains('"cookie":"foo=bar"')
197+
cy.getCookie('foo').its('value').should('equal', 'bar')
174198
})
175199
})
176200
})

packages/driver/cypress/plugins/server.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,14 @@ const createApp = (port) => {
283283
res.send(`<html><body><h1>Welcome, ${user}!</h1></body></html>`)
284284
})
285285

286+
app.get('/set-cookie', (req, res) => {
287+
const { cookie } = req.query
288+
289+
res
290+
.append('Set-Cookie', cookie)
291+
.sendStatus(200)
292+
})
293+
286294
let _var = ''
287295

288296
app.get('/set-var', (req, res) => {

packages/proxy/lib/http/response-middleware.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -400,14 +400,12 @@ const MaybePreventCaching: ResponseMiddleware = function () {
400400
const checkIfNeedsCrossOriginHandling = (ctx: HttpMiddlewareThis<ResponseMiddlewareProps>) => {
401401
const currentAUTUrl = ctx.getAUTUrl()
402402

403-
// A cookie needs cross origin handling if it's an AUT request and
404-
// either the request itself is cross-origin or the origins between
405-
// requests don't match, since the browser won't set them in that
406-
// case and if it's secondary-origin -> primary-origin, we don't
407-
// recognize the request as cross-origin
403+
// A cookie needs cross origin handling if the request itself is
404+
// cross-origin or the origins between requests don't match,
405+
// since the browser won't set them in that case and if it's
406+
// secondary-origin -> primary-origin, we don't recognize the request as cross-origin
408407
return (
409408
ctx.config.experimentalSessionAndOrigin
410-
&& ctx.req.isAUTFrame
411409
&& (
412410
(currentAUTUrl && !cors.urlOriginsMatch(currentAUTUrl, ctx.req.proxiedUrl))
413411
|| !ctx.remoteStates.isPrimaryOrigin(ctx.req.proxiedUrl)

packages/proxy/test/unit/http/response-middleware.spec.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -932,7 +932,6 @@ describe('http/response-middleware', function () {
932932
req: {
933933
proxiedUrl: 'http://www.foobar.com/login',
934934
headers: {},
935-
isAUTFrame: true,
936935
...props.req,
937936
},
938937
incomingResStream: {

0 commit comments

Comments
 (0)