Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 1804f73

Browse filesBrowse files
SkyZeroZxleonsenft
authored andcommitted
fix(service-worker): preserve referrer in asset requests
Preserve referrer metadata when the service worker reconstructs asset requests for cache-busted and redirected asset fetches. For example, an attacker with access to asset host logs could receive a reset token embedded in a page URL if the reconstructed request falls back to default referrer behavior instead of carrying referrer: ''. (cherry picked from commit 99ad47e)
1 parent 91df739 commit 1804f73
Copy full SHA for 1804f73

3 files changed

+46-5Lines changed: 46 additions & 5 deletions

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎packages/service-worker/worker/src/assets.ts‎

Copy file name to clipboardExpand all lines: packages/service-worker/worker/src/assets.ts
+5-4Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -501,10 +501,10 @@ export abstract class AssetGroup {
501501
* Create a new `Request` based on the specified URL and `RequestInit` options, preserving only
502502
* metadata that are known to be safe.
503503
*
504-
* Currently, headers, redirect policy, an explicit `credentials: 'omit'`, and the HTTP cache
505-
* mode are preserved. On cross-origin redirects, sensitive headers are removed. This includes
506-
* `Authorization`, as required by the Fetch redirect algorithm, and forbidden request headers
507-
* that could contain credentials.
504+
* Currently, headers, referrer, redirect policy, an explicit `credentials: 'omit'`, and the HTTP
505+
* cache mode are preserved. On cross-origin redirects, sensitive headers are removed. This
506+
* includes `Authorization`, as required by the Fetch redirect algorithm, and forbidden request
507+
* headers that could contain credentials.
508508
*
509509
* NOTE:
510510
* `credentials: 'same-origin'` and `credentials: 'include'` are intentionally not preserved.
@@ -532,6 +532,7 @@ export abstract class AssetGroup {
532532

533533
const init: RequestInit = {
534534
headers,
535+
referrer: options.referrer,
535536
redirect: options.redirect,
536537
};
537538

Collapse file

‎packages/service-worker/worker/test/happy_spec.ts‎

Copy file name to clipboardExpand all lines: packages/service-worker/worker/test/happy_spec.ts
+36Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1672,6 +1672,22 @@ import {envIsSupported} from '../testing/utils';
16721672
expect(bazReq.credentials).toBe('omit');
16731673
});
16741674

1675+
it(`passes 'referrer' through to the server`, async () => {
1676+
const reqInit = {referrer: 'http://localhost/profile?token=secret'};
1677+
expect(await makeRequest(scope, '/baz.txt', undefined, reqInit)).toBe('this is baz');
1678+
1679+
const [bazReq] = server.getRequestsFor('/baz.txt');
1680+
expect(bazReq.referrer).toBe('http://localhost/profile?token=secret');
1681+
});
1682+
1683+
it(`passes 'referrer: ""' through to the server`, async () => {
1684+
const reqInit = {referrer: ''};
1685+
expect(await makeRequest(scope, '/baz.txt', undefined, reqInit)).toBe('this is baz');
1686+
1687+
const [bazReq] = server.getRequestsFor('/baz.txt');
1688+
expect(bazReq.referrer).toBe('');
1689+
});
1690+
16751691
it(`passes 'cache' through to the server`, async () => {
16761692
// Request a lazy-cached asset (so that it is fetched from the network) and provide an
16771693
// explicit HTTP cache mode.
@@ -1765,6 +1781,26 @@ import {envIsSupported} from '../testing/utils';
17651781
expect(redirectReq.credentials).toBe('omit');
17661782
});
17671783

1784+
it(`passes 'referrer' through to the server`, async () => {
1785+
const reqInit = {referrer: 'http://localhost/profile?token=secret'};
1786+
expect(await makeRequest(scope, '/lazy/redirected.txt', undefined, reqInit)).toBe(
1787+
'this was a redirect too',
1788+
);
1789+
1790+
const [redirectReq] = server.getRequestsFor('/lazy/redirect-target.txt');
1791+
expect(redirectReq.referrer).toBe('http://localhost/profile?token=secret');
1792+
});
1793+
1794+
it(`passes 'referrer: ""' through to the server`, async () => {
1795+
const reqInit = {referrer: ''};
1796+
expect(await makeRequest(scope, '/lazy/redirected.txt', undefined, reqInit)).toBe(
1797+
'this was a redirect too',
1798+
);
1799+
1800+
const [redirectReq] = server.getRequestsFor('/lazy/redirect-target.txt');
1801+
expect(redirectReq.referrer).toBe('');
1802+
});
1803+
17681804
it(`passes 'cache' through to the server`, async () => {
17691805
// Request a redirected, lazy-cached asset (so that it is fetched from the network) and
17701806
// provide an explicit HTTP cache mode.
Collapse file

‎packages/service-worker/worker/testing/fetch.ts‎

Copy file name to clipboardExpand all lines: packages/service-worker/worker/testing/fetch.ts
+5-1Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ export class MockRequest extends MockBody implements Request {
130130
readonly method: string = 'GET';
131131
readonly mode: RequestMode = 'cors';
132132
readonly redirect: RequestRedirect = 'follow';
133-
readonly referrer: string = '';
133+
readonly referrer: string = 'about:client';
134134
readonly referrerPolicy: ReferrerPolicy = 'no-referrer';
135135
readonly signal: AbortSignal = null as any;
136136

@@ -163,6 +163,9 @@ export class MockRequest extends MockBody implements Request {
163163
if (init.redirect !== undefined) {
164164
this.redirect = init.redirect;
165165
}
166+
if (init.referrer !== undefined) {
167+
this.referrer = init.referrer;
168+
}
166169
if (init.destination !== undefined) {
167170
this.destination = init.destination;
168171
}
@@ -179,6 +182,7 @@ export class MockRequest extends MockBody implements Request {
179182
credentials: this.credentials,
180183
headers: this.headers,
181184
redirect: this.redirect,
185+
referrer: this.referrer,
182186
});
183187
}
184188
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.