Add optional read-only access token to mitigate CREEP (CVE-2025-36852)#13
Open
joh-klein wants to merge 1 commit into
Open
Add optional read-only access token to mitigate CREEP (CVE-2025-36852)#13joh-klein wants to merge 1 commit into
joh-klein wants to merge 1 commit into
Conversation
A single read-write token means every cache consumer can also write, so untrusted CI jobs (e.g. PR builds) holding the token can pre-seed the cache entry for a hash a trusted branch will later compute — the CREEP attack. The 409-on-existing immutability does not cover this: the attack writes first, it never overwrites. Add an optional READ_ONLY_ACCESS_TOKEN. The auth middleware accepts either token for GET, but only SERVICE_ACCESS_TOKEN for writes; a read-only token on a non-GET request gets 403 Forbidden. Both tokens are always compared in constant time so timing does not reveal which one matched. Config validation rejects an empty read-only token and a read-only token equal to the service token. Backwards compatible: without READ_ONLY_ACCESS_TOKEN set, behavior is unchanged. Closes nxcite#12 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
joh-klein
added a commit
to meddevo/nx-cache-server
that referenced
this pull request
Jul 17, 2026
Nx rejects a bodyless 401 with 'Misconfigured remote cache endpoint: Requests should respond with text/plain on 401s.' The auth middleware returned bare StatusCode (empty body) for missing/invalid tokens (401) and for read-only-token write attempts (403 - the PR nxcite#13 CREEP path). Route both through ServerError so they carry a text/plain body. Adds a ServerError::Forbidden variant and contract tests for both. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements #12.
What
An optional
READ_ONLY_ACCESS_TOKEN(env or--read-only-access-token). When set:/v1/cache/{hash}: accepted with either token/v1/cache/{hash}: requiresSERVICE_ACCESS_TOKEN; the read-only token gets 403 ForbiddenThis enables the standard CREEP mitigation topology for shared caches: trusted branches (main/release) get the read-write token, untrusted jobs (PR builds) get the read-only one — they still benefit from cache hits but cannot pre-seed/poison entries that trusted builds will consume.
Design notes
READ_ONLY_ACCESS_TOKEN, behavior is byte-for-byte unchanged.ct_eq, as before), so response timing doesn't reveal which token matched.docs/index.htmlenv-var block kept in sync.Testing
e2e against MinIO, all passing:
/healthwithout tokencargo build+cargo fmtclean.🤖 Generated with Claude Code