Spring Security CVE-2026-41707: a bounded DPoP cache enabled replay after eviction
DPoPProofJwtDecoderFactory could forget a used jti after cache pressure. We explain replay preconditions, fixed versions and OAuth 2.0 monitoring.
- AUTHOR
- Karol Rapacz / CEO Breachroad · OSCP · PNPT
- PUBLISHED
- 26 August 2026
- READING TIME
- 16 min read
- TOPIC
- Identity and Access
CVE-2026-41707 affects DPoPProofJwtDecoderFactory in Spring Security. The component remembered the jti values of accepted DPoP proofs so the same signed JWT could not be used twice. Its cache, however, had a strict size limit. An attacker holding an intercepted valid proof could fill the cache with other requests, evict the protected entry and then replay the original proof.
Spring rates the issue High, CVSS 3.1 7.4. The vendor advisory is dated 20 August, while the CVE record entered the public catalogue in the overnight 26 August Central European cycle. Affected releases are Spring Security 7.1.0, 7.0.0–7.0.6 and 6.5.0–6.5.11. Open-source fixes are 7.1.1 and 7.0.7; Spring lists Enterprise Support releases for selected older branches.
What DPoP is designed to protect
With a conventional OAuth 2.0 bearer token, anyone who learns the value can use it. DPoP, or Demonstrating Proof of Possession, binds token use to a client’s cryptographic key. The client attaches a signed proof JWT containing information such as the HTTP method, target URI, time and unique jti. The server verifies the signature and request context.
A signature alone does not prevent replay of the same valid message. The jti and time window provide replay protection: after accepting an identifier, the resource server must recognise its next use. This is security state. If the implementation forgets the jti before the proof becomes unacceptable, the old signature looks fresh to the validator again.
DPoP limits the value of a stolen access token when the thief lacks the private key, but this CVE does not mean anyone on the network can defeat DPoP. The advisory explicitly assumes that the attacker can intercept a valid user proof. They must then force eviction and replay it while other checks—time, method, URI and token binding—still permit it.
Why a bounded cache became a security flaw
A fixed-size cache is normally an availability control. It prevents unbounded memory growth under unique client input. The conflict arises when cache contents are the only memory that a credential was already consumed. Eviction policy optimises resources; it does not preserve the invariant “this identifier remains spent for the entire replay window”.
If an attacker can submit enough syntactically acceptable unique jti values, earlier entries are displaced. Even LRU cannot distinguish a victim’s entry from attacker noise. Once the identifier disappears, the decoder has no evidence that it saw it before, so a repeated proof is processed as the first use.
This is a classic conflict between bounded memory and stateful security. A safe design needs capacity for the maximum accepted-proof rate multiplied by the replay window, or a TTL store whose semantics do not remove entries early. Another option is to reject new proofs when safe capacity is exhausted, although that shifts risk towards denial of service. Eviction is not free when each entry records a security decision.
Real-world exploitation preconditions
First, the application must use the affected DPoPProofJwtDecoderFactory; merely including Spring Security is not sufficient. The endpoint must then accept DPoP and allow the attacker to generate traffic that creates many new entries. Finally, the attacker needs a valid victim proof, perhaps through client compromise, over-detailed header logging, a vulnerable proxy or a separate channel weakness.
The CVSS Attack Complexity is High, reflecting those conditions. That is not a reason to skip the patch. DPoP is deployed precisely where an organisation wants to reduce the effect of token interception. If anti-replay fails in an interception scenario, the feature misses a central business objective.
Spring describes unauthorised access and victim impersonation, with high confidentiality and integrity impact and no direct availability impact in the CVSS vector. The reachable data and operations still depend on the access token, URI and method bound to the captured proof.
Fixed versions
Spring lists 7.1.0, 7.0.0–7.0.6 and 6.5.0–6.5.11 as affected. Open-source users should move to 7.1.1 or 7.0.7. The vendor table also lists 7.1.0.1, 7.0.6.1 and 6.5.12 in the relevant Enterprise Support channels.
In Spring Boot applications, inspect the resolved spring-security-* modules. The Boot version and BOM indicate a likely line, but dependency overrides, a parent POM, lockfile or cached image layer can change the runtime. Strong evidence comes from the build dependency tree, image SBOM and deployed artifact manifest.
The vendor says no further mitigation is required after upgrading. That describes removal of the library flaw, not a reason to abandon monitoring. If the environment ran an affected release, teams still need to assess whether proofs or tokens leaked and whether logs show cache pressure.
A safe deployment plan
Identify every resource server using DPoP and determine whether instances share replay state. In a cluster, a local cache in each pod gives each instance a separate view of spent jti values; a load balancer may route replays across nodes. That architecture is outside the narrow CVE description but belongs in the anti-replay review.
Upgrade to a fixed dependency, rebuild the artifact and image from a clean layer, and verify the dependency tree. Regression tests should confirm first-use acceptance, replay rejection, method and URI binding, and stable protection under a large volume of unique identifiers. Do not test exploit candidates against production; use a controlled, isolated staging environment.
Roll out through a canary and watch DPoP errors, latency, memory and 401/403 rates. A rise in rejections may reveal a client incorrectly reusing a proof or previously invisible replay traffic. Do not weaken validation to silence errors quickly; correct proof generation in the client.
Detection and investigation
Telemetry should correlate a pseudonymised or hashed jti, key fingerprint, client, method, normalised URI and verification outcome. Never log complete access tokens or proofs, because the log would become the credential source required by the attack. Identifier retention should cover the accepted time window and investigation needs.
Look for a sudden rise in unique jti values from one client, key or source, followed by the return of an earlier identifier. IP distribution should not defeat correlation by key and client ID. Exact repetition of method, URI and jti after unusual volume is also a useful signal.
If replay is confirmed, revoke the related access token, investigate how the proof was intercepted and rotate the client key where appropriate. The patch closes the eviction path, but it does not repair secret logging, a compromised device, or a proxy copying sensitive headers into an untrusted observability system.
Design lesson: security memory has a lifetime
Rate limits, nonces, jti values, revocation lists and one-time tokens preserve negative knowledge: “do not accept this again”. Ordinary cache pressure must not delete that state before its decision expires. Capacity should be designed from traffic budget, TTL and overload behaviour.
Tests should cover more than two identical requests in succession. Place a volume of unique elements larger than normal capacity between them, restart a process, switch pods and traverse different load-balancer paths. Those conditions reveal the difference between a functional cache and a durable replay barrier.
Source facts and Breachroad conclusions
The eviction mechanism, captured-proof precondition, impact, CVSS score, affected versions and fixes come from Spring’s advisory and the CVE record. The sources do not report active exploitation. Telemetry, cluster, state-pressure testing and incident-response recommendations are Breachroad conclusions.
OAuth, identity and secure coding training helps teams design correct replay boundaries, while application and API penetration testing can assess DPoP, proxies and resource-server behaviour under load.


