Overview
CVE-2017-8046 describes a deserialization-related vulnerability where malicious PATCH requests to servers using older Spring Data REST and Spring Boot components could trigger the deserialization of attacker-controlled JSON data, leading to arbitrary Java code execution on the server. This class of flaw arises when an application binds untrusted JSON input directly to domain objects and enables polymorphic deserialization, a capability that can instantiate and invoke code paths the developer did not intend. In practice, an attacker could craft a JSON payload that, when deserialized, caused the server to execute arbitrary methods or load classes, potentially compromising the entire application. The vulnerability has been mapped to CWE-20 (Improper Input Validation), illustrating how untrusted input, if not properly constrained, can lead to dangerous behavior during deserialization. The affected combinations include Spring Data REST versions prior to 2.6.9 (Ingalls SR9) and prior to 3.0.1 (Kay SR1) alongside Spring Boot versions prior to 1.5.9 and 2.0 M6. This real-world exposure manifested as remote code execution risks in API endpoints exposed by Spring Boot applications using these older libraries.
Affected Versions
Spring Data REST prior to 2.6.9 (Ingalls SR9) or prior to 3.0.1 (Kay SR1); Spring Boot prior to 1.5.9, 2.0 M6
Code Fix Example
Spring Boot API Security Remediation
Vulnerable pattern and fix (Java):
import com.fasterxml.jackson.databind.ObjectMapper;
public class SSRFDeserializationDemo {
public static void main(String[] args) throws Exception {
// 1) Vulnerable pattern: enabling polymorphic typing can allow attacker-controlled types to be instantiated during deserialization
String vulnerableJson = "{\"name\": \"example\"}";
ObjectMapper vulnerableMapper = new ObjectMapper();
vulnerableMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
Object vulnerableObj = vulnerableMapper.readValue(vulnerableJson, Object.class);
// 2) Fixed pattern: disable polymorphic typing to prevent deserialization of attacker-controlled types
String safeJson = "{\"name\": \"example\"}";
ObjectMapper safeMapper = new ObjectMapper();
safeMapper.disableDefaultTyping();
Object safeObj = safeMapper.readValue(safeJson, Object.class);
}
}