Skip to content

fix(cache): check Authorization on request headers per RFC 9111 §3.5#4911

Open
metalix2 wants to merge 1 commit intonodejs:mainfrom
metalix2:CacheAuthorizationRequestHeader
Open

fix(cache): check Authorization on request headers per RFC 9111 §3.5#4911
metalix2 wants to merge 1 commit intonodejs:mainfrom
metalix2:CacheAuthorizationRequestHeader

Conversation

@metalix2
Copy link
Contributor

@metalix2 metalix2 commented Mar 19, 2026

This relates to...

RFC 9111 §3.5 - Storing Responses to Authenticated Requests I believe I've identified a bug within the cacheHandler logic. I was writing some integration tests which were validating the expected RFC 9111 standards when requests with Authorization headers were being incorrectly cached.

Rationale

canCacheResponse() checked resHeaders.authorization (response headers) for the Authorization guard. Since Authorization is a request header, this check was dead code — shared caches would store responses to authenticated requests regardless of
directives, violating RFC 9111 §3.5.

Changes

Thread reqHeaders (from CacheKey.headers) into canCacheResponse() and check request headers instead of response headers for the Authorization guard.

Features

N/A

Bug Fixes

  • Check reqHeaders.authorization instead of resHeaders.authorization in canCacheResponse()
  • Accept s-maxage and must-revalidate as permitting directives alongside public, per RFC 9111 §3.5
  • Add 5 tests covering the Authorization caching matrix:
    • Auth + public → cached
    • Auth + s-maxage → cached
    • Auth + must-revalidate → cached
    • Auth + max-age only → not cached
    • Auth + no directives → not cached

Breaking Changes and Deprecations

Responses to requests containing an Authorization header that previously leaked into shared caches (due to the dead-code bug) will now correctly be excluded unless the response carries public, s-maxage, or must-revalidate. This is a correctness fix, not a feature change.

Benchmarks


  ┌─────────────────────┬─────────┬───────────────────┬───────────┬─────────────────┐                                                                                                                                                                         
  │        Test         │ Samples │      Result       │ Tolerance │ Diff vs slowest │                                                                                                                                                                         
  ├─────────────────────┼─────────┼───────────────────┼───────────┼─────────────────┤                                                                                                                                                                         
  │ http - no keepalive │ 101     │ 3,371.91 req/sec  │ ± 21.07%  │ -               │                                                                                                                                                                         
  ├─────────────────────┼─────────┼───────────────────┼───────────┼─────────────────┤                                                                                                                                                                         
  │ http - keepalive    │ 101     │ 4,090.87 req/sec  │ ± 28.33%  │ + 21.32%        │
  ├─────────────────────┼─────────┼───────────────────┼───────────┼─────────────────┤
  │ request             │ 101     │ 8,764.62 req/sec  │ ± 6.75%   │ + 159.93%       │
  ├─────────────────────┼─────────┼───────────────────┼───────────┼─────────────────┤
  │ got                 │ 101     │ 9,146.79 req/sec  │ ± 4.63%   │ + 171.26%       │
  ├─────────────────────┼─────────┼───────────────────┼───────────┼─────────────────┤
  │ axios               │ 101     │ 9,319.81 req/sec  │ ± 4.15%   │ + 176.40%       │
  ├─────────────────────┼─────────┼───────────────────┼───────────┼─────────────────┤
  │ node-fetch          │ 101     │ 9,887.99 req/sec  │ ± 5.30%   │ + 193.25%       │
  ├─────────────────────┼─────────┼───────────────────┼───────────┼─────────────────┤
  │ undici - fetch      │ 101     │ 10,416.91 req/sec │ ± 7.36%   │ + 208.93%       │
  ├─────────────────────┼─────────┼───────────────────┼───────────┼─────────────────┤
  │ superagent          │ 101     │ 11,185.81 req/sec │ ± 3.84%   │ + 231.74%       │
  ├─────────────────────┼─────────┼───────────────────┼───────────┼─────────────────┤
  │ undici - dispatch   │ 101     │ 13,091.94 req/sec │ ± 6.11%   │ + 288.26%       │
  ├─────────────────────┼─────────┼───────────────────┼───────────┼─────────────────┤
  │ undici - stream     │ 101     │ 13,357.09 req/sec │ ± 6.03%   │ + 296.13%       │
  ├─────────────────────┼─────────┼───────────────────┼───────────┼─────────────────┤
  │ undici - request    │ 101     │ 13,727.02 req/sec │ ± 5.51%   │ + 307.10%       │
  ├─────────────────────┼─────────┼───────────────────┼───────────┼─────────────────┤
  │ undici - pipeline   │ 101     │ 13,835.44 req/sec │ ± 3.23%   │ + 310.31%       │
  └─────────────────────┴─────────┴───────────────────┴───────────┴─────────────────┘

Status

@@ -372,8 +373,16 @@ function canCacheResponse (cacheType, statusCode, resHeaders, cacheControlDirect
}

// https://www.rfc-editor.org/rfc/rfc9111.html#name-storing-responses-to-authen
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code now does what is described in the comment.

@metalix2 metalix2 force-pushed the CacheAuthorizationRequestHeader branch from feacffc to b029a95 Compare March 20, 2026 09:13
@codecov-commenter
Copy link

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.94%. Comparing base (51fd661) to head (b029a95).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4911      +/-   ##
==========================================
+ Coverage   92.92%   92.94%   +0.01%     
==========================================
  Files         112      112              
  Lines       35646    35655       +9     
==========================================
+ Hits        33123    33138      +15     
+ Misses       2523     2517       -6     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants