Overview
The CVE-2018-11040 vulnerability describes a JSONP misconfiguration in certain Spring Framework and Spring Boot setups where cross-domain requests can be inadvertently enabled. When MappingJackson2JsonView is configured and the AbstractJsonpResponseBodyAdvice is active, REST endpoints can be invoked with JSONP parameters (jsonp or callback), allowing attackers to execute cross-domain script requests that receive JSON payloads wrapped in a JavaScript function. This effectively bypasses the browser same-origin policy for the affected endpoints and can lead to data leakage if sensitive information is exposed. The issue is categorized under CWE-829 in the context of insecure handling of data exposure via JSONP wrappers, and a patch was released to prevent enabling JSONP by default in patched versions. In practice, improperly exposing endpoints that return sensitive data through JSONP can enable an attacker to exfiltrate data by loading a malicious page that invokes those endpoints through a script tag.
In real-world Spring Boot applications, this vulnerability manifests when developers explicitly configure JSON view support and attach a JSONP response advisor, triggering JSONP wrapping for requests that include a callback parameter. Even though JSONP support is not enabled by default, the presence of MappingJackson2JsonView in the view layer and an AbstractJsonpResponseBodyAdvice bean makes the endpoint vulnerable to cross-domain data access if an attacker can coerce a victim’s browser to request the endpoint via a script tag. Upgrading the framework to patched versions is essential to remove or constrain this behavior and to ensure JSONP is not inadvertently enabled.
Remediation involves removing permissive JSONP handling from the Spring Boot application, ensuring endpoints do not respond with JSONP wrappers, and adopting safer cross-origin mechanisms such as proper CORS configuration. If JSONP must be maintained for legacy reasons, isolate those endpoints, enforce strict data exposure policies, and validate callbacks against a allowlist. Also, upgrade to the patched Spring Framework versions to ensure the JSONP exposure is not present by default.
To align with best practices, rely on standard, secure REST patterns with explicit access controls (OAuth2/JWT, CSRF protection where applicable) and use CORS rather than JSONP for cross-origin access where possible.
Affected Versions
Spring Framework 5.0.x prior to 5.0.7 and 4.3.x prior to 4.3.18, and older unsupported versions
Code Fix Example
Spring Boot API Security Remediation
Vulnerable pattern (JSONP enabled via MappingJackson2JsonView and AbstractJsonpResponseBodyAdvice):
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.AbstractJsonpResponseBodyAdvice;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Bean
public MappingJackson2JsonView jsonView() {
// JSON responses are rendered via a view; can be used with JSONP wrappers
return new MappingJackson2JsonView();
}
}
@ControllerAdvice
public class JsonpAdvice extends AbstractJsonpResponseBodyAdvice {
public JsonpAdvice() {
// enables JSONP for callbacks named jsonp or callback
super("jsonp", "callback");
}
}
@RestController
@RequestMapping("/api")
class UserController {
@GetMapping("/users")
public List<String> users() {
return List.of("Alice", "Bob");
}
}
Fixed pattern (JSONP handling removed; CORS-based approach used):
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
// Use safe CORS configuration instead of JSONP
registry.addMapping("/api/**")
.allowedOrigins("https://trusted.example.com")
.allowedMethods("GET", "POST");
}
}
@RestController
@RequestMapping("/api")
class UserController {
@GetMapping("/users")
public List<String> users() {
return List.of("Alice", "Bob");
}
}