Skip to content

Commit 01b0d22

Browse files
committed
fix(backend): guard primary cross-origin sync handshake against non-GET requests
1 parent f99d77f commit 01b0d22

2 files changed

Lines changed: 34 additions & 0 deletions

File tree

packages/backend/src/tokens/__tests__/request.test.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1815,6 +1815,39 @@ describe('tokens.authenticateRequest(options)', () => {
18151815
});
18161816
});
18171817

1818+
test('does not trigger handshake for cross-origin POST document request on primary domain', async () => {
1819+
const cookieStr = Object.entries({
1820+
__session: mockJwt,
1821+
__client_uat: '12345',
1822+
})
1823+
.map(([k, v]) => `${k}=${v}`)
1824+
.join(';');
1825+
1826+
const request = new Request('https://primary.com/dashboard', {
1827+
method: 'POST',
1828+
headers: {
1829+
...defaultHeaders,
1830+
referer: 'https://satellite.com/form',
1831+
'sec-fetch-dest': 'document',
1832+
cookie: cookieStr,
1833+
},
1834+
});
1835+
1836+
const requestState = await authenticateRequest(request, {
1837+
...mockOptions(),
1838+
publishableKey: PK_LIVE,
1839+
domain: 'primary.com',
1840+
isSatellite: false,
1841+
signInUrl: 'https://primary.com/sign-in',
1842+
});
1843+
1844+
expect(requestState).toBeSignedIn({
1845+
domain: 'primary.com',
1846+
isSatellite: false,
1847+
signInUrl: 'https://primary.com/sign-in',
1848+
});
1849+
});
1850+
18181851
test('does not trigger handshake for non-document requests', async () => {
18191852
const request = mockRequestWithCookies(
18201853
{

packages/backend/src/tokens/request.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -652,6 +652,7 @@ export const authenticateRequest: AuthenticateRequest = (async (
652652
// Check for cross-origin requests from satellite domains to primary domain
653653
const shouldForceHandshakeForCrossDomain =
654654
!authenticateContext.isSatellite && // We're on primary
655+
authenticateContext.method === 'GET' && // Only GET navigations (POST form submissions set sec-fetch-dest: document too)
655656
authenticateContext.secFetchDest === 'document' && // Document navigation
656657
authenticateContext.isCrossOriginReferrer() && // Came from different domain
657658
!authenticateContext.isKnownClerkReferrer() && // Not from Clerk accounts portal or FAPI

0 commit comments

Comments
 (0)