Get ahead
VMware offers training and certification to turbo-charge your progress.
Learn moreSpring Data REST does not preserve the persisted version (@Version) property of an aggregate
root when handling an HTTP PUT against an immutable target type.
For mutable aggregates, the PUT merge logic explicitly retains the stored identifier and version
properties, discarding any client-supplied values. For immutable aggregates — Java records, Kotlin
data classes, all-args @PersistenceCreator types — or when a polymorphic (@JsonTypeInfo) subtype
change occurs, the merge instead returns the request-body object and restores only Jackson
@JsonIgnore-marked properties from storage. The version property is not among those, and while the
identifier is re-applied from the persisted entity by the request-handling layer, the version is not.
As a result, an authenticated client with PUT access can submit a version value in the request body
that is honoured and persisted. This defeats optimistic-locking (lost-update) protection for
applications that rely on @Version rather than mandatory If-Match/ETag preconditions, allowing a
stale write to be silently accepted and a concurrent update to be overwritten.
Affected applications are those that expose a Spring Data REST repository whose aggregate root is an
immutable type (or permits a body-driven polymorphic subtype change) and that declares a version
property visible to Jackson's deserialization model and not excluded via @JsonIgnore.
Spring Data REST:
| Fix version | Availability |
|---|---|
| 5.1.1 | OSS |
| 5.1.0.1 | Enterprise Support Only |
| 5.0.7 | OSS |
| 5.0.6.1 | Enterprise Support Only |
| 4.5.13 | Enterprise Support Only |
| 4.4.16 | Enterprise Support Only |
| 3.7.21 | Enterprise Support Only |
No further mitigation steps are necessary.
To report a security vulnerability for a project within the Spring portfolio, see the Security Policy