Skip to content

@cache: an authorized request on a ttl=0/None route gets Cache-Control without private #362

Description

@allen0099

Found during the docs audit (#361).

Problem

@cache adds private to a response when the request carries a credential (Authorization, a session the middleware loaded, or a non-empty request.session), so a shared cache never stores a response meant for one caller. That check is skipped whenever the route already bypasses the backend (private=True, or ttl of None/0), see fastapi_cachex/cache.py:1178 and :1224-1228. For private=True that is harmless, since private is already sent. For a non-positive ttl it is not:

@app.get("/a")
@cache(ttl=0, must_revalidate=True)
async def a(): ...
Request Cache-Control
GET /a with Authorization: Bearer x max-age=0, must-revalidate
@cache(ttl=60) route, same request private, max-age=60

RFC 9111 §3.5 lets a shared cache store an authorized response that carries must-revalidate (or public, or s-maxage) without private, so a CDN or proxy in front of the app may serve one user's response to another after revalidation.

Proposal

Run the credential check for every GET the decorator handles, not only for routes that read the backend: when a credential is present and the route did not ask for private/no-store, add private regardless of ttl. Add tests for ttl=0/None with each credential kind.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinghttp-cacheThe @cache decorator, cache keys and Cache-Control handlingsecuritySecurity vulnerability or hardening

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions