Security context
Medium· 5.9GHSA-f26x-pr96-vw86 CVE-2018-11040CWE-829Published Oct 16, 2018

Moderate severity vulnerability that affects org.springframework:spring-core

Research this vulnerability

Research is free — Hunters explains how the bug works, the root-cause code pattern, how the fix addresses it, and how to test whether a target is affected, in chat. Investigate & write exploit is a paid run — the engine reads the advisory and fix commits, then builds and validates a working proof-of-concept exploit with reproduction steps.

Affected versions

5.0.0.RELEASE → fixed in 5.0.7.RELEASE4.3.0.RELEASE → fixed in 4.3.18.RELEASE

Details

Spring Framework, versions 5.0.x prior to 5.0.7 and 4.3.x prior to 4.3.18 and older unsupported versions, allows web applications to enable cross-domain requests via JSONP (JSON with Padding) through AbstractJsonpResponseBodyAdvice for REST controllers and MappingJackson2JsonView for browser requests. Both are not enabled by default in Spring Framework nor Spring Boot, however, when MappingJackson2JsonView is configured in an application, JSONP support is automatically ready to use through the "jsonp" and "callback" JSONP parameters, enabling cross-domain requests.

The fix

Deprecate JSONP and disable it by default in Jackson view

Sebastien Deleuze· Jun 8, 2018, 10:29 AM+4811874859493b
spring-web/src/main/java/org/springframework/http/converter/json/MappingJackson2HttpMessageConverter.java+3 1
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2016 the original author or authors.
+ * Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -88,6 +88,7 @@ public void setPrefixJson(boolean prefixJson) {
@Override
+ @SuppressWarnings("deprecation")
protected void writePrefix(JsonGenerator generator, Object object) throws IOException {
if (this.jsonPrefix != null) {
generator.writeRaw(this.jsonPrefix);
@@ -101,6 +102,7 @@ protected void writePrefix(JsonGenerator generator, Object object) throws IOExce
}
@Override
+ @SuppressWarnings("deprecation")
protected void writeSuffix(JsonGenerator generator, Object object) throws IOException {
String jsonpFunction =
(object instanceof MappingJacksonValue ? ((MappingJacksonValue) object).getJsonpFunction() : null);
spring-web/src/main/java/org/springframework/http/converter/json/MappingJacksonValue.java+7 1
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -108,14 +108,20 @@ public FilterProvider getFilters() {
/**
* Set the name of the JSONP function name.
+ * @deprecated Will be removed as of Spring Framework 5.1, use
+ * <a href="https://docs.spring.io/spring/docs/4.3.x/spring-framework-reference/html/cors.html">CORS</a> instead.
*/
+ @Deprecated
public void setJsonpFunction(String functionName) {
this.jsonpFunction = functionName;
}
/**
* Return the configured JSONP function name.
+ * @deprecated Will be removed as of Spring Framework 5.1, use
+ * <a href="https://docs.spring.io/spring/docs/4.3.x/spring-framework-reference/html/cors.html">CORS</a> instead.
*/
+ @Deprecated
public String getJsonpFunction() {
return this.jsonpFunction;
}
spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/AbstractJsonpResponseBodyAdvice.java+4 1
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -45,7 +45,10 @@
*
* @author Rossen Stoyanchev
* @since 4.1
+ * @deprecated Will be removed as of Spring Framework 5.1, use
+ * <a href="https://docs.spring.io/spring/docs/4.3.x/spring-framework-reference/html/cors.html">CORS</a> instead.
*/
+@Deprecated
public abstract class AbstractJsonpResponseBodyAdvice extends AbstractMappingJacksonResponseBodyAdvice {
/**
spring-webmvc/src/main/java/org/springframework/web/servlet/view/json/MappingJackson2JsonView.java+12 3
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,7 +17,6 @@
package org.springframework.web.servlet.view.json;
import java.io.IOException;
-import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashSet;
@@ -58,6 +57,7 @@
* @author Sebastien Deleuze
* @since 3.1.2
*/
+@SuppressWarnings("deprecation")
public class MappingJackson2JsonView extends AbstractJackson2View {
/**
@@ -68,7 +68,10 @@ public class MappingJackson2JsonView extends AbstractJackson2View {
/**
* Default content type for JSONP: "application/javascript".
+ * @deprecated Will be removed as of Spring Framework 5.1, use
+ * <a href="https://docs.spring.io/spring/docs/4.3.x/spring-framework-reference/html/cors.html">CORS</a> instead.
*/
+ @Deprecated
public static final String DEFAULT_JSONP_CONTENT_TYPE = "application/javascript";
/**
@@ -83,7 +86,7 @@ public class MappingJackson2JsonView extends AbstractJackson2View {
private boolean extractValueFromSingleKeyModel = false;
- private Set<String> jsonpParameterNames = new LinkedHashSet<String>(Arrays.asList("jsonp", "callback"));
+ private Set<String> jsonpParameterNames = new LinkedHashSet<String>();
/**
@@ -168,7 +171,10 @@ public void setExtractValueFromSingleKeyModel(boolean extractValueFromSingleKeyM
* <p>The parameter names configured by default are "jsonp" and "callback".
* @since 4.1
* @see <a href="http://en.wikipedia.org/wiki/JSONP">JSONP Wikipedia article</a>
+ * @deprecated Will be removed as of Spring Framework 5.1, use
+ * <a href="https://docs.spring.io/spring/docs/4.3.x/spring-framework-reference/html/cors.html">CORS</a> instead.
*/
+ @Deprecated
public void setJsonpParameterNames(Set<String> jsonpParameterNames) {
this.jsonpParameterNames = jsonpParameterNames;
}
@@ -198,7 +204,10 @@ private String getJsonpParameterValue(HttpServletRequest request) {
* Invalid parameter values are ignored.
* @param value the query param value, never {@code null}
* @since 4.1.8
+ * @deprecated Will be removed as of Spring Framework 5.1, use
+ * <a href="https://docs.spring.io/spring/docs/4.3.x/spring-framework-reference/html/cors.html">CORS</a> instead.
*/
+ @Deprecated
protected boolean isValidJsonpQueryParam(String value) {
return CALLBACK_PARAM_PATTERN.matcher(value).matches();
}
spring-webmvc/src/test/java/org/springframework/web/servlet/view/json/MappingJackson2JsonViewTests.java+12 2
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,9 +17,11 @@
package org.springframework.web.servlet.view.json;
import java.io.IOException;
+import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
@@ -324,11 +326,19 @@ public void renderSimpleBeanWithFilters() throws Exception {
@Test
public void renderWithJsonp() throws Exception {
+ testJsonp("jsonp", "callback", false);
+ testJsonp("jsonp", "_callback", false);
+ testJsonp("jsonp", "_Call.bAcK", false);
+ testJsonp("jsonp", "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_.", false);
+ testJsonp("jsonp", "<script>", false);
+ testJsonp("jsonp", "!foo!bar", false);
+
+ this.view.setJsonpParameterNames(new LinkedHashSet<String>(Arrays.asList("jsonp")));
+
testJsonp("jsonp", "callback", true);
testJsonp("jsonp", "_callback", true);
testJsonp("jsonp", "_Call.bAcK", true);
testJsonp("jsonp", "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_.", true);
-
testJsonp("jsonp", "<script>", false);
testJsonp("jsonp", "!foo!bar", false);
}
spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/TransportType.java+5 1
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,6 +27,8 @@
/**
* SockJS transport types.
*
+ * <p>JSONP support will be removed as of Spring Framework 5.1, use others transports instead.
+ *
* @author Rossen Stoyanchev
* @author Sebastien Deleuze
* @since 4.0
@@ -39,8 +41,10 @@ public enum TransportType {
XHR_SEND("xhr_send", HttpMethod.POST, "cors", "jsessionid", "no_cache"),
+ @Deprecated
JSONP("jsonp", HttpMethod.GET, "jsessionid", "no_cache"),
+ @Deprecated
JSONP_SEND("jsonp_send", HttpMethod.POST, "jsessionid", "no_cache"),
XHR_STREAMING("xhr_streaming", HttpMethod.POST, "cors", "jsessionid", "no_cache"),
spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/handler/DefaultSockJsService.java+2 1
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2014 the original author or authors.
+ * Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -78,6 +78,7 @@ public DefaultSockJsService(TaskScheduler scheduler, Collection<TransportHandler
}
+ @SuppressWarnings("deprecation")
private static Set<TransportHandler> getDefaultTransportHandlers(Collection<TransportHandler> overrides) {
Set<TransportHandler> result = new LinkedHashSet<TransportHandler>(8);
result.add(new XhrPollingTransportHandler());
spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/handler/JsonpPollingTransportHandler.java+3 1
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2014 the original author or authors.
+ * Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -40,7 +40,9 @@
*
* @author Rossen Stoyanchev
* @since 4.0
+ * @deprecated Will be removed as of Spring Framework 5.1, use others transports instead.
*/
+@Deprecated
public class JsonpPollingTransportHandler extends AbstractHttpSendingTransportHandler {
@Override
More files changed — see the full commit.

Deprecate JSONP and disable it by default in Jackson view

Sebastien Deleuze· Jun 8, 2018, 10:31 AM+5011b80c13b722
spring-web/src/main/java/org/springframework/http/converter/json/MappingJackson2HttpMessageConverter.java+3 1
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2017 the original author or authors.
+ * Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -91,6 +91,7 @@ public void setPrefixJson(boolean prefixJson) {
@Override
+ @SuppressWarnings("deprecation")
protected void writePrefix(JsonGenerator generator, Object object) throws IOException {
if (this.jsonPrefix != null) {
generator.writeRaw(this.jsonPrefix);
@@ -104,6 +105,7 @@ protected void writePrefix(JsonGenerator generator, Object object) throws IOExce
}
@Override
+ @SuppressWarnings("deprecation")
protected void writeSuffix(JsonGenerator generator, Object object) throws IOException {
String jsonpFunction =
(object instanceof MappingJacksonValue ? ((MappingJacksonValue) object).getJsonpFunction() : null);
spring-web/src/main/java/org/springframework/http/converter/json/MappingJacksonValue.java+7 1
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2017 the original author or authors.
+ * Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -115,14 +115,20 @@ public FilterProvider getFilters() {
/**
* Set the name of the JSONP function name.
+ * @deprecated Will be removed as of Spring Framework 5.1, use
+ * <a href="https://docs.spring.io/spring/docs/5.0.x/spring-framework-reference/web.html#mvc-cors">CORS</a> instead.
*/
+ @Deprecated
public void setJsonpFunction(@Nullable String functionName) {
this.jsonpFunction = functionName;
}
/**
* Return the configured JSONP function name.
+ * @deprecated Will be removed as of Spring Framework 5.1, use
+ * <a href="https://docs.spring.io/spring/docs/5.0.x/spring-framework-reference/web.html#mvc-cors">CORS</a> instead.
*/
+ @Deprecated
@Nullable
public String getJsonpFunction() {
return this.jsonpFunction;
spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/AbstractJsonpResponseBodyAdvice.java+4 1
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -45,7 +45,10 @@
*
* @author Rossen Stoyanchev
* @since 4.1
+ * @deprecated Will be removed as of Spring Framework 5.1, use
+ * <a href="https://docs.spring.io/spring/docs/5.0.x/spring-framework-reference/web.html#mvc-cors">CORS</a> instead.
*/
+@Deprecated
public abstract class AbstractJsonpResponseBodyAdvice extends AbstractMappingJacksonResponseBodyAdvice {
/**
spring-webmvc/src/main/java/org/springframework/web/servlet/view/json/MappingJackson2JsonView.java+14 3
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2017 the original author or authors.
+ * Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -59,6 +59,7 @@
* @author Sebastien Deleuze
* @since 3.1.2
*/
+@SuppressWarnings("deprecation")
public class MappingJackson2JsonView extends AbstractJackson2View {
/**
@@ -69,7 +70,10 @@ public class MappingJackson2JsonView extends AbstractJackson2View {
/**
* Default content type for JSONP: "application/javascript".
+ * @deprecated Will be removed as of Spring Framework 5.1, use
+ * <a href="https://docs.spring.io/spring/docs/5.0.x/spring-framework-reference/web.html#mvc-cors">CORS</a> instead.
*/
+ @Deprecated
public static final String DEFAULT_JSONP_CONTENT_TYPE = "application/javascript";
/**
@@ -87,7 +91,7 @@ public class MappingJackson2JsonView extends AbstractJackson2View {
private boolean extractValueFromSingleKeyModel = false;
@Nullable
- private Set<String> jsonpParameterNames = new LinkedHashSet<>(Arrays.asList("jsonp", "callback"));
+ private Set<String> jsonpParameterNames = new LinkedHashSet<>();
/**
@@ -170,10 +174,14 @@ public void setExtractValueFromSingleKeyModel(boolean extractValueFromSingleKeyM
* Set JSONP request parameter names. Each time a request has one of those
* parameters, the resulting JSON will be wrapped into a function named as
* specified by the JSONP request parameter value.
- * <p>The parameter names configured by default are "jsonp" and "callback".
+ * <p>As of Spring Framework 5.0.7, there is no parameter name configured
+ * by default.
* @since 4.1
* @see <a href="http://en.wikipedia.org/wiki/JSONP">JSONP Wikipedia article</a>
+ * @deprecated Will be removed as of Spring Framework 5.1, use
+ * <a href="https://docs.spring.io/spring/docs/5.0.x/spring-framework-reference/web.html#mvc-cors">CORS</a> instead.
*/
+ @Deprecated
public void setJsonpParameterNames(Set<String> jsonpParameterNames) {
this.jsonpParameterNames = jsonpParameterNames;
}
@@ -204,7 +212,10 @@ private String getJsonpParameterValue(HttpServletRequest request) {
* Invalid parameter values are ignored.
* @param value the query param value, never {@code null}
* @since 4.1.8
+ * @deprecated Will be removed as of Spring Framework 5.1, use
+ * <a href="https://docs.spring.io/spring/docs/5.0.x/spring-framework-reference/web.html#mvc-cors">CORS</a> instead.
*/
+ @Deprecated
protected boolean isValidJsonpQueryParam(String value) {
return CALLBACK_PARAM_PATTERN.matcher(value).matches();
}
spring-webmvc/src/test/java/org/springframework/web/servlet/view/json/MappingJackson2JsonViewTests.java+12 2
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2016 the original author or authors.
+ * Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,9 +17,11 @@
package org.springframework.web.servlet.view.json;
import java.io.IOException;
+import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
@@ -324,11 +326,19 @@ public void renderSimpleBeanWithFilters() throws Exception {
@Test
public void renderWithJsonp() throws Exception {
+ testJsonp("jsonp", "callback", false);
+ testJsonp("jsonp", "_callback", false);
+ testJsonp("jsonp", "_Call.bAcK", false);
+ testJsonp("jsonp", "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_.", false);
+ testJsonp("jsonp", "<script>", false);
+ testJsonp("jsonp", "!foo!bar", false);
+
+ this.view.setJsonpParameterNames(new LinkedHashSet<>(Arrays.asList("jsonp")));
+
testJsonp("jsonp", "callback", true);
testJsonp("jsonp", "_callback", true);
testJsonp("jsonp", "_Call.bAcK", true);
testJsonp("jsonp", "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_.", true);
-
testJsonp("jsonp", "<script>", false);
testJsonp("jsonp", "!foo!bar", false);
}
spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/TransportType.java+5 1
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2017 the original author or authors.
+ * Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,6 +28,8 @@
/**
* SockJS transport types.
*
+ * <p>JSONP support will be removed as of Spring Framework 5.1, use others transports instead.
+ *
* @author Rossen Stoyanchev
* @author Sebastien Deleuze
* @since 4.0
@@ -40,8 +42,10 @@ public enum TransportType {
XHR_SEND("xhr_send", HttpMethod.POST, "cors", "jsessionid", "no_cache"),
+ @Deprecated
JSONP("jsonp", HttpMethod.GET, "jsessionid", "no_cache"),
+ @Deprecated
JSONP_SEND("jsonp_send", HttpMethod.POST, "jsessionid", "no_cache"),
XHR_STREAMING("xhr_streaming", HttpMethod.POST, "cors", "jsessionid", "no_cache"),
spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/handler/DefaultSockJsService.java+2 1
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2016 the original author or authors.
+ * Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -79,6 +79,7 @@ public DefaultSockJsService(TaskScheduler scheduler, Collection<TransportHandler
}
+ @SuppressWarnings("deprecation")
private static Set<TransportHandler> getDefaultTransportHandlers(@Nullable Collection<TransportHandler> overrides) {
Set<TransportHandler> result = new LinkedHashSet<>(8);
result.add(new XhrPollingTransportHandler());
spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/handler/JsonpPollingTransportHandler.java+3 1
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2016 the original author or authors.
+ * Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -41,7 +41,9 @@
*
* @author Rossen Stoyanchev
* @since 4.0
+ * @deprecated Will be removed as of Spring Framework 5.1, use others transports instead.
*/
+@Deprecated
public class JsonpPollingTransportHandler extends AbstractHttpSendingTransportHandler {
@Override
More files changed — see the full commit.

References