@angular/service-worker: Request Credential & Cache Policy Stripping
Description
Angular Service Worker strips explicit credentials and cache settings from fetch requests, causing unintended credential exposure and cache persistence.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Angular Service Worker strips explicit `credentials` and `cache` settings from fetch requests, causing unintended credential exposure and cache persistence.
Vulnerability
In the @angular/service-worker package, the internal request reconstruction helper function strips explicit client-defined safety parameters (credentials and cache mode) from intercepted fetch requests, reverting them to browser defaults (credentials: 'same-origin' and default HTTP cache behavior). This affects all versions prior to the fix introduced in PR #68904 [1][2].
Exploitation
An attacker can exploit this vulnerability when the target application has an active Angular Service Worker, asset group patterns match the fetch request URLs, and the client-side code uses fetch() with explicit credentials: 'omit' or cache: 'no-store'. No additional attacker privileges are required; the service worker automatically strips the safety parameters upon interception [1][2].
Impact
Successful exploitation leads to two main consequences: (1) same-origin credentials (cookies, Authorization headers) are sent to endpoints that should not receive them, potentially enabling session hijacking; (2) private or non-cacheable resources are stored in the service worker cache, persisting after logout and allowing unauthorized access to sensitive data [1][2].
Mitigation
The fix is available in PR #68904, which preserves the explicit credentials and cache settings during request reconstruction [3]. Users should update @angular/service-worker to the patched version. As a temporary workaround, developers can avoid using credentials: 'omit' or cache: 'no-store' on fetch requests that match asset group patterns, or restructure asset groups to exclude such requests [1].
AI Insight generated on Jun 15, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected products
1Patches
131399c217106fix(service-worker): Preserves HTTP cache mode in asset group requests
3 files changed · +36 −1
packages/service-worker/worker/src/assets.ts+9 −1 modified@@ -501,12 +501,16 @@ export abstract class AssetGroup { * Create a new `Request` based on the specified URL and `RequestInit` options, preserving only * metadata that are known to be safe. * - * Currently, headers, redirect policy, and an explicit `credentials: 'omit'` are preserved. + * Currently, headers, redirect policy, an explicit `credentials: 'omit'`, and the HTTP cache + * mode are preserved. * * NOTE: * `credentials: 'same-origin'` and `credentials: 'include'` are intentionally not preserved. * Forwarding `'include'` could leak cookies to cross-origin asset hosts, and forwarding * `'same-origin'` matches the default `fetch()` behavior so there is nothing to preserve. + * Requests with `cache: 'only-if-cached'` and `mode !== 'same-origin'` are short-circuited + * earlier in `Driver.onFetch()` (they are a known Chrome DevTools quirk), so no special + * handling for that combination is needed here. * TODO(gkalpak): * Investigate preserving more metadata. See, also, discussion on preserving `mode`: * https://github.com/angular/angular/issues/41931#issuecomment-1227601347. @@ -521,6 +525,10 @@ export abstract class AssetGroup { init.credentials = 'omit'; } + if (options.cache !== undefined) { + init.cache = options.cache; + } + return this.adapter.newRequest(url, init); }
packages/service-worker/worker/test/happy_spec.ts+26 −0 modified@@ -1667,6 +1667,18 @@ import {envIsSupported} from '../testing/utils'; expect(bazReq.credentials).toBe('omit'); }); + it(`passes 'cache' through to the server`, async () => { + // Request a lazy-cached asset (so that it is fetched from the network) and provide an + // explicit HTTP cache mode. + const reqInit = {cache: 'no-store'}; + expect(await makeRequest(scope, '/baz.txt', undefined, reqInit)).toBe('this is baz'); + + // Verify that the explicit `cache` value was preserved (instead of being replaced by the + // default `'default'`). + const [bazReq] = server.getRequestsFor('/baz.txt'); + expect(bazReq.cache).toBe('no-store'); + }); + describe('for redirect requests', () => { it('passes headers through to the server', async () => { // Request a redirected, lazy-cached asset (so that it is fetched from the network) and @@ -1721,6 +1733,20 @@ import {envIsSupported} from '../testing/utils'; const [redirectReq] = server.getRequestsFor('/lazy/redirect-target.txt'); expect(redirectReq.credentials).toBe('omit'); }); + + it(`passes 'cache' through to the server`, async () => { + // Request a redirected, lazy-cached asset (so that it is fetched from the network) and + // provide an explicit HTTP cache mode. + const reqInit = {cache: 'no-store'}; + expect(await makeRequest(scope, '/lazy/redirected.txt', undefined, reqInit)).toBe( + 'this was a redirect too', + ); + + // Verify that the explicit `cache` value was preserved across the redirect + // reconstruction (instead of being replaced by the default `'default'`). + const [redirectReq] = server.getRequestsFor('/lazy/redirect-target.txt'); + expect(redirectReq.cache).toBe('no-store'); + }); }); });
packages/service-worker/worker/testing/fetch.ts+1 −0 modified@@ -167,6 +167,7 @@ export class MockRequest extends MockBody implements Request { } return new MockRequest(this.url, { body: this._body, + cache: this.cache, mode: this.mode, credentials: this.credentials, headers: this.headers,
Vulnerability mechanics
Root cause
"Missing forwarding of the HTTP cache mode (and credentials) during service-worker request reconstruction causes developer-specified safety parameters to be silently replaced with browser defaults."
Attack vector
An attacker exploits this by relying on the Angular Service Worker's asset-group interception. When a client-side fetch call uses `{ cache: 'no-store' }` to prevent caching of sensitive data, the service worker's reconstruction helper drops that directive, reverting to the browser default cache behavior. This causes private or non-cacheable resources to be stored in the service worker's cache storage, making them accessible or persistent post-logout. The same mechanism also strips `credentials: 'omit'`, causing the browser to attach same-origin cookies or Authorization headers to outbound requests where the developer explicitly intended them to be omitted, potentially leaking session credentials to unintended endpoints [patch_id=6084656].
Affected code
The vulnerability resides in `packages/service-worker/worker/src/assets.ts` within the `AssetGroup` class's request-reconstruction helper. The helper function was preserving `headers`, `redirect` policy, and an explicit `credentials: 'omit'`, but it did **not** forward the HTTP `cache` mode from the original request. The patch adds a check: `if (options.cache !== undefined) { init.cache = options.cache; }` so that an explicit cache mode (e.g. `'no-store'`) is carried through to the new `Request` object [patch_id=6084656].
What the fix does
The patch modifies the `AssetGroup` request-reconstruction helper in `assets.ts` to forward the original request's `cache` property when it is explicitly set. Previously only `headers`, `redirect` policy, and `credentials: 'omit'` were preserved; the `cache` mode was silently dropped, causing every reconstructed request to use the browser default (`'default'`). By adding `if (options.cache !== undefined) { init.cache = options.cache; }`, the fix ensures that a developer-specified cache mode such as `'no-store'` is honored, preventing unintended caching of sensitive responses [patch_id=6084656].
Preconditions
- configThe target application uses @angular/service-worker with an active ngsw-worker.js registration.
- configAn assetGroups pattern in ngsw-config.json matches the target dynamic routing endpoint.
- authThe victim has an active authentication state (same-origin session cookies or auth headers).
- inputThe application initiates a fetch call with explicit safety parameters such as { cache: 'no-store' } or { credentials: 'omit' } to a route matched by the service worker.
Generated on Jun 15, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
3News mentions
0No linked articles in our index yet.