Up-to-date guidelines for serialization-based endpoints
Issue: SPR-15317
This commit is contained in:
		
							parent
							
								
									b90d3d0e88
								
							
						
					
					
						commit
						2236262fc6
					
				| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>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!
 | 
			
		||||
 * <p>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.)
 | 
			
		||||
 *
 | 
			
		||||
 * <p><b>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.</b>
 | 
			
		||||
 * In general, we strongly recommend any other message format (e.g. JSON) instead.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @since 1.1
 | 
			
		||||
 * @see #setServiceUrl
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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.</b>
 | 
			
		||||
 * 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<Object> {
 | 
			
		||||
public class HttpInvokerProxyFactoryBean extends HttpInvokerClientInterceptor implements FactoryBean<Object> {
 | 
			
		||||
 | 
			
		||||
	private Object serviceProxy;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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.</b>
 | 
			
		||||
 * 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.
 | 
			
		||||
	 * <p>Delegates to
 | 
			
		||||
	 * {@link #readRemoteInvocation(javax.servlet.http.HttpServletRequest, java.io.InputStream)}
 | 
			
		||||
	 * with the
 | 
			
		||||
	 * {@link javax.servlet.ServletRequest#getInputStream() servlet request's input stream}.
 | 
			
		||||
	 * <p>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.
 | 
			
		||||
	 *
 | 
			
		||||
	 * <p>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 <a href="https://jira.spring.io/browse/SPR-14040">SPR-14040</a>
 | 
			
		||||
	 */
 | 
			
		||||
	private static class FlushGuardedOutputStream extends FilterOutputStream {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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.
 | 
			
		||||
 *
 | 
			
		||||
 * <p><b>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.</b>
 | 
			
		||||
 * 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.
 | 
			
		||||
	 * <p>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}.
 | 
			
		||||
	 * <p>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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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"]
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 `<jee:jndi-lookup>`). 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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue