Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 582a417

Browse files
Yenya030alxhub
authored andcommitted
fix(http): exclude withCredentials requests from transfer cache
Update the transfer cache check to safely exclude all requests sent with the `withCredentials` flag. By default, the HTTP transfer cache avoids caching user-specific responses to prevent sensitive data exposure or incorrect caching. While requests with explicit headers like `Cookie` or `Authorization` are excluded by default, requests can also be sent with credentials via the `withCredentials` flag without having those headers explicitly declared on the request object. To keep user-specific responses from being cached, exclude `withCredentials` requests unconditionally, even when the `includeRequestsWithAuthHeaders` option is set to true. (cherry picked from commit 34090cb)
1 parent 5c6d6df commit 582a417

3 files changed

Lines changed: 26 additions & 3 deletions

File tree

‎adev/src/content/guide/ssr.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,7 @@ To configure this, update your `angular.json` file as follows:
432432
You can customize how Angular caches HTTP responses during server‑side rendering (SSR) and reuses them during hydration by configuring `HttpTransferCacheOptions`.
433433
This configuration is provided globally using `withHttpTransferCacheOptions` inside `provideClientHydration()`.
434434

435-
By default, `HttpClient` caches all `HEAD` and `GET` requests which don't contain `Authorization`, `Proxy-Authorization`, or `Cookie` headers. You can override those settings by using `withHttpTransferCacheOptions` to the hydration configuration.
435+
By default, `HttpClient` caches all `HEAD` and `GET` requests which don't contain `Authorization`, `Proxy-Authorization`, or `Cookie` headers and are not sent with `withCredentials`. You can override those settings by using `withHttpTransferCacheOptions` to the hydration configuration.
436436

437437
```ts
438438
import {bootstrapApplication} from '@angular/platform-browser';
@@ -487,7 +487,7 @@ Use this only when `POST` requests are **idempotent** and safe to reuse between
487487
### `includeRequestsWithAuthHeaders`
488488

489489
Determines whether requests containing `Authorization`, `Proxy‑Authorization`, or `Cookie` headers are eligible for caching.
490-
By default, these are excluded to prevent caching user‑specific responses.
490+
By default, these are excluded to prevent caching user‑specific responses. Requests sent with `withCredentials` are also excluded by default.
491491

492492
```ts
493493
withHttpTransferCacheOptions({

‎packages/common/http/src/transfer_cache.ts‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ import {HttpParams} from './params';
4242
* (for example using GraphQL).
4343
* @param includeRequestsWithAuthHeaders Enables caching of requests containing `Authorization`,
4444
* `Proxy-Authorization`, or `Cookie` headers. By default, these requests are excluded from
45-
* caching.
45+
* caching. Requests sent using `withCredentials` are also excluded by default.
4646
*
4747
* @see [Configuring the caching options](guide/ssr#configuring-the-caching-options)
4848
*
@@ -131,6 +131,8 @@ function shouldCacheRequest(req: HttpRequest<unknown>, options: CacheOptions): b
131131
if (
132132
!isCacheActive ||
133133
requestOptions === false ||
134+
// Do not cache requests sent with credentials.
135+
req.withCredentials ||
134136
// POST requests are allowed either globally or at request level
135137
(requestMethod === 'POST' && !globalOptions.includePostRequests && !requestOptions) ||
136138
(requestMethod !== 'POST' && !ALLOWED_METHODS.includes(requestMethod)) ||

‎packages/common/http/test/transfer_cache_spec.ts‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ interface RequestParams {
4040
observe?: 'body' | 'response';
4141
transferCache?: {includeHeaders: string[]} | boolean;
4242
headers?: {[key: string]: string};
43+
withCredentials?: boolean;
4344
body?: RequestBody;
4445
}
4546

@@ -429,6 +430,16 @@ describe('TransferCache', () => {
429430
makeRequestAndExpectOne('/test-auth', 'foo');
430431
});
431432

433+
it('should not cache requests with credentials', async () => {
434+
makeRequestAndExpectOne('/test-auth', 'foo', {
435+
withCredentials: true,
436+
});
437+
438+
makeRequestAndExpectOne('/test-auth', 'foo', {
439+
withCredentials: true,
440+
});
441+
});
442+
432443
it('should cache POST with the differing body in string form', () => {
433444
makeRequestAndExpectOne('/test-1', null, {method: 'POST', transferCache: true, body: 'foo'});
434445
makeRequestAndExpectNone('/test-1', 'POST', {transferCache: true, body: 'foo'});
@@ -581,6 +592,16 @@ describe('TransferCache', () => {
581592
makeRequestAndExpectNone('/test-auth');
582593
});
583594

595+
it(`should not cache requests with credentials when 'includeRequestsWithAuthHeaders' is 'true'`, async () => {
596+
makeRequestAndExpectOne('/test-auth', 'foo', {
597+
withCredentials: true,
598+
});
599+
600+
makeRequestAndExpectOne('/test-auth', 'foo', {
601+
withCredentials: true,
602+
});
603+
});
604+
584605
it('should cache a POST request', () => {
585606
makeRequestAndExpectOne('/include?foo=1', 'post-body', {method: 'POST'});
586607

0 commit comments

Comments
 (0)