diff --git a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/AbstractHttpInvokerRequestExecutor.java b/spring-web/src/main/java/org/springframework/remoting/httpinvoker/AbstractHttpInvokerRequestExecutor.java index 8b6c47b339..2b976d32ec 100644 --- a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/AbstractHttpInvokerRequestExecutor.java +++ b/spring-web/src/main/java/org/springframework/remoting/httpinvoker/AbstractHttpInvokerRequestExecutor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2017 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. @@ -43,14 +43,15 @@ import org.springframework.util.Assert; * @since 1.1 * @see #doExecuteRequest */ -public abstract class AbstractHttpInvokerRequestExecutor - implements HttpInvokerRequestExecutor, BeanClassLoaderAware { +public abstract class AbstractHttpInvokerRequestExecutor implements HttpInvokerRequestExecutor, BeanClassLoaderAware { /** * Default content type: "application/x-java-serialized-object" */ public static final String CONTENT_TYPE_SERIALIZED_OBJECT = "application/x-java-serialized-object"; + private static final int SERIALIZED_INVOCATION_BYTE_ARRAY_INITIAL_SIZE = 1024; + protected static final String HTTP_METHOD_POST = "POST"; @@ -67,9 +68,6 @@ public abstract class AbstractHttpInvokerRequestExecutor protected static final String ENCODING_GZIP = "gzip"; - private static final int SERIALIZED_INVOCATION_BYTE_ARRAY_INITIAL_SIZE = 1024; - - protected final Log logger = LogFactory.getLog(getClass()); private String contentType = CONTENT_TYPE_SERIALIZED_OBJECT; diff --git a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerClientInterceptor.java b/spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerClientInterceptor.java index c72ad254b6..c6703e9d7f 100644 --- a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerClientInterceptor.java +++ b/spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerClientInterceptor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 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. @@ -46,14 +46,19 @@ import org.springframework.remoting.support.RemoteInvocationResult; * a security context). Furthermore, it allows to customize request * execution via the {@link HttpInvokerRequestExecutor} strategy. * - *

Can use the JDK's {@link java.rmi.server.RMIClassLoader} to load - * classes from a given {@link #setCodebaseUrl codebase}, performing - * on-demand dynamic code download from a remote location. The codebase - * can consist of multiple URLs, separated by spaces. Note that - * RMIClassLoader requires a SecurityManager to be set, analogous to - * when using dynamic class download with standard RMI! + *

Can use the JDK's {@link java.rmi.server.RMIClassLoader} to load classes + * from a given {@link #setCodebaseUrl codebase}, performing on-demand dynamic + * code download from a remote location. The codebase can consist of multiple + * URLs, separated by spaces. Note that RMIClassLoader requires a SecurityManager + * to be set, analogous to when using dynamic class download with standard RMI! * (See the RMI documentation for details.) * + *

WARNING: Be aware of vulnerabilities due to unsafe Java deserialization: + * Manipulated input streams could lead to unwanted code execution on the server + * during the deserialization step. As a consequence, do not expose HTTP invoker + * endpoints to untrusted clients but rather just between your own services. + * In general, we strongly recommend any other message format (e.g. JSON) instead. + * * @author Juergen Hoeller * @since 1.1 * @see #setServiceUrl diff --git a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerProxyFactoryBean.java b/spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerProxyFactoryBean.java index 8850398a53..19e6d95513 100644 --- a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerProxyFactoryBean.java +++ b/spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerProxyFactoryBean.java @@ -40,6 +40,7 @@ import org.springframework.beans.factory.FactoryBean; * Manipulated input streams could lead to unwanted code execution on the server * during the deserialization step. As a consequence, do not expose HTTP invoker * endpoints to untrusted clients but rather just between your own services. + * In general, we strongly recommend any other message format (e.g. JSON) instead. * * @author Juergen Hoeller * @since 1.1 @@ -51,8 +52,7 @@ import org.springframework.beans.factory.FactoryBean; * @see org.springframework.remoting.rmi.RmiProxyFactoryBean * @see org.springframework.remoting.caucho.HessianProxyFactoryBean */ -public class HttpInvokerProxyFactoryBean extends HttpInvokerClientInterceptor - implements FactoryBean { +public class HttpInvokerProxyFactoryBean extends HttpInvokerClientInterceptor implements FactoryBean { private Object serviceProxy; diff --git a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerServiceExporter.java b/spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerServiceExporter.java index 15332cc17a..ad309397e9 100644 --- a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerServiceExporter.java +++ b/spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerServiceExporter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 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. @@ -52,6 +52,7 @@ import org.springframework.web.util.NestedServletException; * Manipulated input streams could lead to unwanted code execution on the server * during the deserialization step. As a consequence, do not expose HTTP invoker * endpoints to untrusted clients but rather just between your own services. + * In general, we strongly recommend any other message format (e.g. JSON) instead. * * @author Juergen Hoeller * @since 1.1 @@ -60,8 +61,7 @@ import org.springframework.web.util.NestedServletException; * @see org.springframework.remoting.rmi.RmiServiceExporter * @see org.springframework.remoting.caucho.HessianServiceExporter */ -public class HttpInvokerServiceExporter extends RemoteInvocationSerializingExporter - implements HttpRequestHandler { +public class HttpInvokerServiceExporter extends RemoteInvocationSerializingExporter implements HttpRequestHandler { /** * Reads a remote invocation from the request, executes it, @@ -86,10 +86,8 @@ public class HttpInvokerServiceExporter extends RemoteInvocationSerializingExpor /** * Read a RemoteInvocation from the given HTTP request. - *

Delegates to - * {@link #readRemoteInvocation(javax.servlet.http.HttpServletRequest, java.io.InputStream)} - * with the - * {@link javax.servlet.ServletRequest#getInputStream() servlet request's input stream}. + *

Delegates to {@link #readRemoteInvocation(HttpServletRequest, InputStream)} with + * the {@link HttpServletRequest#getInputStream() servlet request's input stream}. * @param request current HTTP request * @return the RemoteInvocation object * @throws IOException in case of I/O failure @@ -205,12 +203,10 @@ public class HttpInvokerServiceExporter extends RemoteInvocationSerializingExpor /** * Decorate an {@code OutputStream} to guard against {@code flush()} calls, * which are turned into no-ops. - * *

Because {@link ObjectOutputStream#close()} will in fact flush/drain * the underlying stream twice, this {@link FilterOutputStream} will * guard against individual flush calls. Multiple flush calls can lead * to performance issues, since writes aren't gathered as they should be. - * * @see SPR-14040 */ private static class FlushGuardedOutputStream extends FilterOutputStream { diff --git a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/SimpleHttpInvokerServiceExporter.java b/spring-web/src/main/java/org/springframework/remoting/httpinvoker/SimpleHttpInvokerServiceExporter.java index 0463fbedf2..142d8b5ace 100644 --- a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/SimpleHttpInvokerServiceExporter.java +++ b/spring-web/src/main/java/org/springframework/remoting/httpinvoker/SimpleHttpInvokerServiceExporter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 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,6 +45,12 @@ import org.springframework.remoting.support.RemoteInvocationResult; * being tied to Java. Nevertheless, it is as easy to set up as Hessian, * which is its main advantage compared to RMI. * + *

WARNING: Be aware of vulnerabilities due to unsafe Java deserialization: + * Manipulated input streams could lead to unwanted code execution on the server + * during the deserialization step. As a consequence, do not expose HTTP invoker + * endpoints to untrusted clients but rather just between your own services. + * In general, we strongly recommend any other message format (e.g. JSON) instead. + * * @author Juergen Hoeller * @since 2.5.1 * @see org.springframework.remoting.httpinvoker.HttpInvokerClientInterceptor @@ -52,15 +58,14 @@ import org.springframework.remoting.support.RemoteInvocationResult; * @see org.springframework.remoting.caucho.SimpleHessianServiceExporter */ @UsesSunHttpServer -public class SimpleHttpInvokerServiceExporter extends RemoteInvocationSerializingExporter - implements HttpHandler { +public class SimpleHttpInvokerServiceExporter extends RemoteInvocationSerializingExporter implements HttpHandler { /** * Reads a remote invocation from the request, executes it, * and writes the remote invocation result to the response. - * @see #readRemoteInvocation(com.sun.net.httpserver.HttpExchange) - * @see #invokeAndCreateResult(org.springframework.remoting.support.RemoteInvocation, Object) - * @see #writeRemoteInvocationResult(com.sun.net.httpserver.HttpExchange, org.springframework.remoting.support.RemoteInvocationResult) + * @see #readRemoteInvocation(HttpExchange) + * @see #invokeAndCreateResult(RemoteInvocation, Object) + * @see #writeRemoteInvocationResult(HttpExchange, RemoteInvocationResult) */ @Override public void handle(HttpExchange exchange) throws IOException { @@ -78,10 +83,8 @@ public class SimpleHttpInvokerServiceExporter extends RemoteInvocationSerializin /** * Read a RemoteInvocation from the given HTTP request. - *

Delegates to - * {@link #readRemoteInvocation(com.sun.net.httpserver.HttpExchange, java.io.InputStream)} - * with the - * {@link com.sun.net.httpserver.HttpExchange#getRequestBody()} request's input stream}. + *

Delegates to {@link #readRemoteInvocation(HttpExchange, InputStream)} + * with the {@link HttpExchange#getRequestBody()} request's input stream}. * @param exchange current HTTP request/response * @return the RemoteInvocation object * @throws java.io.IOException in case of I/O failure diff --git a/src/asciidoc/data-access.adoc b/src/asciidoc/data-access.adoc index ebba2ae879..347c89a7a1 100644 --- a/src/asciidoc/data-access.adoc +++ b/src/asciidoc/data-access.adoc @@ -6651,13 +6651,13 @@ which consists of string aliases mapped to classes: [WARNING] ==== - -By default, XStream allows for arbitrary classes to be unmarshalled, which can result in -security vulnerabilities. As such, it is __not recommended to use the +By default, XStream allows for arbitrary classes to be unmarshalled, which can lead to +unsafe Java serialization effects. As such, it is __not recommended to use the `XStreamMarshaller` to unmarshal XML from external sources__ (i.e. the Web), as this can -result in __security vulnerabilities__. If you do use the `XStreamMarshaller` to -unmarshal XML from an external source, set the `supportedClasses` property on the -`XStreamMarshaller`, like so: +result in __security vulnerabilities__. + +If you choose to use the `XStreamMarshaller` to unmarshal XML from an external source, +set the `supportedClasses` property on the `XStreamMarshaller`, like as follows: [source,xml,indent=0] [subs="verbatim,quotes"] diff --git a/src/asciidoc/integration.adoc b/src/asciidoc/integration.adoc index 1b45fc48d7..9d15ae74b1 100644 --- a/src/asciidoc/integration.adoc +++ b/src/asciidoc/integration.adoc @@ -377,6 +377,21 @@ advanced and easier-to-use functionality. Refer to http://hc.apache.org/httpcomponents-client-ga/[hc.apache.org/httpcomponents-client-ga/] for more information. +[WARNING] +==== +Be aware of vulnerabilities due to unsafe Java deserialization: +Manipulated input streams could lead to unwanted code execution on the server +during the deserialization step. As a consequence, do not expose HTTP invoker +endpoints to untrusted clients but rather just between your own services. +In general, we strongly recommend any other message format (e.g. JSON) instead. + +If you are concerned about security vulnerabilities due to Java serialization, +consider the general-purpose serialization filter mechanism at the core JVM level, +originally developed for JDK 9 but backported to JDK 8, 7 and 6 in the meantime: +https://blogs.oracle.com/java-platform-group/entry/incoming_filter_serialization_data_a +http://openjdk.java.net/jeps/290 +==== + [[remoting-httpinvoker-server]] @@ -2499,7 +2514,7 @@ be obtained from JNDI instead (using ``). The Spring-based mess listeners can then interact with the server-hosted `ResourceAdapter`, also using the server's built-in `WorkManager`. -Please consult the JavaDoc for `JmsMessageEndpointManager`, `JmsActivationSpecConfig`, +Please consult the javadoc for `JmsMessageEndpointManager`, `JmsActivationSpecConfig`, and `ResourceAdapterFactoryBean` for more details. Spring also provides a generic JCA message endpoint manager which is not tied to JMS: @@ -2507,7 +2522,7 @@ Spring also provides a generic JCA message endpoint manager which is not tied to for using any message listener type (e.g. a CCI MessageListener) and any provider-specific ActivationSpec object. Check out your JCA provider's documentation to find out about the actual capabilities of your connector, and consult -`GenericMessageEndpointManager`'s JavaDoc for the Spring-specific configuration details. +`GenericMessageEndpointManager`'s javadoc for the Spring-specific configuration details. [NOTE] ==== @@ -5966,7 +5981,6 @@ along with an inline image. [WARNING] ==== - Inline resources are added to the mime message using the specified `Content-ID` ( `identifier1234` in the above example). The order in which you are adding the text and the resource are __very__ important. Be sure to __first add the text__ and after that