Skip to content

Commit c4fda0e

Browse files
committed
Up-to-date guidelines for serialization-based endpoints
Issue: SPR-15317 (cherry picked from commit 2236262)
1 parent 66670cf commit c4fda0e

File tree

7 files changed

+59
-43
lines changed

7 files changed

+59
-43
lines changed

spring-web/src/main/java/org/springframework/remoting/httpinvoker/AbstractHttpInvokerRequestExecutor.java

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2012 the original author or authors.
2+
* Copyright 2002-2017 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -43,14 +43,15 @@
4343
* @since 1.1
4444
* @see #doExecuteRequest
4545
*/
46-
public abstract class AbstractHttpInvokerRequestExecutor
47-
implements HttpInvokerRequestExecutor, BeanClassLoaderAware {
46+
public abstract class AbstractHttpInvokerRequestExecutor implements HttpInvokerRequestExecutor, BeanClassLoaderAware {
4847

4948
/**
5049
* Default content type: "application/x-java-serialized-object"
5150
*/
5251
public static final String CONTENT_TYPE_SERIALIZED_OBJECT = "application/x-java-serialized-object";
5352

53+
private static final int SERIALIZED_INVOCATION_BYTE_ARRAY_INITIAL_SIZE = 1024;
54+
5455

5556
protected static final String HTTP_METHOD_POST = "POST";
5657

@@ -67,9 +68,6 @@ public abstract class AbstractHttpInvokerRequestExecutor
6768
protected static final String ENCODING_GZIP = "gzip";
6869

6970

70-
private static final int SERIALIZED_INVOCATION_BYTE_ARRAY_INITIAL_SIZE = 1024;
71-
72-
7371
protected final Log logger = LogFactory.getLog(getClass());
7472

7573
private String contentType = CONTENT_TYPE_SERIALIZED_OBJECT;

spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerClientInterceptor.java

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2014 the original author or authors.
2+
* Copyright 2002-2017 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -46,14 +46,19 @@
4646
* a security context). Furthermore, it allows to customize request
4747
* execution via the {@link HttpInvokerRequestExecutor} strategy.
4848
*
49-
* <p>Can use the JDK's {@link java.rmi.server.RMIClassLoader} to load
50-
* classes from a given {@link #setCodebaseUrl codebase}, performing
51-
* on-demand dynamic code download from a remote location. The codebase
52-
* can consist of multiple URLs, separated by spaces. Note that
53-
* RMIClassLoader requires a SecurityManager to be set, analogous to
54-
* when using dynamic class download with standard RMI!
49+
* <p>Can use the JDK's {@link java.rmi.server.RMIClassLoader} to load classes
50+
* from a given {@link #setCodebaseUrl codebase}, performing on-demand dynamic
51+
* code download from a remote location. The codebase can consist of multiple
52+
* URLs, separated by spaces. Note that RMIClassLoader requires a SecurityManager
53+
* to be set, analogous to when using dynamic class download with standard RMI!
5554
* (See the RMI documentation for details.)
5655
*
56+
* <p><b>WARNING: Be aware of vulnerabilities due to unsafe Java deserialization:
57+
* Manipulated input streams could lead to unwanted code execution on the server
58+
* during the deserialization step. As a consequence, do not expose HTTP invoker
59+
* endpoints to untrusted clients but rather just between your own services.</b>
60+
* In general, we strongly recommend any other message format (e.g. JSON) instead.
61+
*
5762
* @author Juergen Hoeller
5863
* @since 1.1
5964
* @see #setServiceUrl

spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerProxyFactoryBean.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
* Manipulated input streams could lead to unwanted code execution on the server
4141
* during the deserialization step. As a consequence, do not expose HTTP invoker
4242
* endpoints to untrusted clients but rather just between your own services.</b>
43+
* In general, we strongly recommend any other message format (e.g. JSON) instead.
4344
*
4445
* @author Juergen Hoeller
4546
* @since 1.1
@@ -52,8 +53,7 @@
5253
* @see org.springframework.remoting.caucho.HessianProxyFactoryBean
5354
* @see org.springframework.remoting.caucho.BurlapProxyFactoryBean
5455
*/
55-
public class HttpInvokerProxyFactoryBean extends HttpInvokerClientInterceptor
56-
implements FactoryBean<Object> {
56+
public class HttpInvokerProxyFactoryBean extends HttpInvokerClientInterceptor implements FactoryBean<Object> {
5757

5858
private Object serviceProxy;
5959

spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerServiceExporter.java

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2016 the original author or authors.
2+
* Copyright 2002-2017 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -52,6 +52,7 @@
5252
* Manipulated input streams could lead to unwanted code execution on the server
5353
* during the deserialization step. As a consequence, do not expose HTTP invoker
5454
* endpoints to untrusted clients but rather just between your own services.</b>
55+
* In general, we strongly recommend any other message format (e.g. JSON) instead.
5556
*
5657
* @author Juergen Hoeller
5758
* @since 1.1
@@ -61,8 +62,7 @@
6162
* @see org.springframework.remoting.caucho.HessianServiceExporter
6263
* @see org.springframework.remoting.caucho.BurlapServiceExporter
6364
*/
64-
public class HttpInvokerServiceExporter extends RemoteInvocationSerializingExporter
65-
implements HttpRequestHandler {
65+
public class HttpInvokerServiceExporter extends RemoteInvocationSerializingExporter implements HttpRequestHandler {
6666

6767
/**
6868
* Reads a remote invocation from the request, executes it,
@@ -87,10 +87,8 @@ public void handleRequest(HttpServletRequest request, HttpServletResponse respon
8787

8888
/**
8989
* Read a RemoteInvocation from the given HTTP request.
90-
* <p>Delegates to
91-
* {@link #readRemoteInvocation(javax.servlet.http.HttpServletRequest, java.io.InputStream)}
92-
* with the
93-
* {@link javax.servlet.ServletRequest#getInputStream() servlet request's input stream}.
90+
* <p>Delegates to {@link #readRemoteInvocation(HttpServletRequest, InputStream)} with
91+
* the {@link HttpServletRequest#getInputStream() servlet request's input stream}.
9492
* @param request current HTTP request
9593
* @return the RemoteInvocation object
9694
* @throws IOException in case of I/O failure
@@ -206,12 +204,10 @@ protected OutputStream decorateOutputStream(
206204
/**
207205
* Decorate an {@code OutputStream} to guard against {@code flush()} calls,
208206
* which are turned into no-ops.
209-
*
210207
* <p>Because {@link ObjectOutputStream#close()} will in fact flush/drain
211208
* the underlying stream twice, this {@link FilterOutputStream} will
212209
* guard against individual flush calls. Multiple flush calls can lead
213210
* to performance issues, since writes aren't gathered as they should be.
214-
*
215211
* @see <a href="https://jira.spring.io/browse/SPR-14040">SPR-14040</a>
216212
*/
217213
private static class FlushGuardedOutputStream extends FilterOutputStream {

spring-web/src/main/java/org/springframework/remoting/httpinvoker/SimpleHttpInvokerServiceExporter.java

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2014 the original author or authors.
2+
* Copyright 2002-2017 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -45,6 +45,12 @@
4545
* expense of being tied to Java. Nevertheless, it is as easy to set up as
4646
* Hessian and Burlap, which is its main advantage compared to RMI.
4747
*
48+
* <p><b>WARNING: Be aware of vulnerabilities due to unsafe Java deserialization:
49+
* Manipulated input streams could lead to unwanted code execution on the server
50+
* during the deserialization step. As a consequence, do not expose HTTP invoker
51+
* endpoints to untrusted clients but rather just between your own services.</b>
52+
* In general, we strongly recommend any other message format (e.g. JSON) instead.
53+
*
4854
* @author Juergen Hoeller
4955
* @since 2.5.1
5056
* @see org.springframework.remoting.httpinvoker.HttpInvokerClientInterceptor
@@ -53,15 +59,14 @@
5359
* @see org.springframework.remoting.caucho.SimpleBurlapServiceExporter
5460
*/
5561
@UsesSunHttpServer
56-
public class SimpleHttpInvokerServiceExporter extends RemoteInvocationSerializingExporter
57-
implements HttpHandler {
62+
public class SimpleHttpInvokerServiceExporter extends RemoteInvocationSerializingExporter implements HttpHandler {
5863

5964
/**
6065
* Reads a remote invocation from the request, executes it,
6166
* and writes the remote invocation result to the response.
62-
* @see #readRemoteInvocation(com.sun.net.httpserver.HttpExchange)
63-
* @see #invokeAndCreateResult(org.springframework.remoting.support.RemoteInvocation, Object)
64-
* @see #writeRemoteInvocationResult(com.sun.net.httpserver.HttpExchange, org.springframework.remoting.support.RemoteInvocationResult)
67+
* @see #readRemoteInvocation(HttpExchange)
68+
* @see #invokeAndCreateResult(RemoteInvocation, Object)
69+
* @see #writeRemoteInvocationResult(HttpExchange, RemoteInvocationResult)
6570
*/
6671
@Override
6772
public void handle(HttpExchange exchange) throws IOException {
@@ -79,10 +84,8 @@ public void handle(HttpExchange exchange) throws IOException {
7984

8085
/**
8186
* Read a RemoteInvocation from the given HTTP request.
82-
* <p>Delegates to
83-
* {@link #readRemoteInvocation(com.sun.net.httpserver.HttpExchange, java.io.InputStream)}
84-
* with the
85-
* {@link com.sun.net.httpserver.HttpExchange#getRequestBody()} request's input stream}.
87+
* <p>Delegates to {@link #readRemoteInvocation(HttpExchange, InputStream)}
88+
* with the {@link HttpExchange#getRequestBody()} request's input stream}.
8689
* @param exchange current HTTP request/response
8790
* @return the RemoteInvocation object
8891
* @throws java.io.IOException in case of I/O failure

src/asciidoc/data-access.adoc

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7037,13 +7037,13 @@ which consists of string aliases mapped to classes:
70377037

70387038
[WARNING]
70397039
====
7040-
7041-
By default, XStream allows for arbitrary classes to be unmarshalled, which can result in
7042-
security vulnerabilities. As such, it is __not recommended to use the
7040+
By default, XStream allows for arbitrary classes to be unmarshalled, which can lead to
7041+
unsafe Java serialization effects. As such, it is __not recommended to use the
70437042
`XStreamMarshaller` to unmarshal XML from external sources__ (i.e. the Web), as this can
7044-
result in __security vulnerabilities__. If you do use the `XStreamMarshaller` to
7045-
unmarshal XML from an external source, set the `supportedClasses` property on the
7046-
`XStreamMarshaller`, like so:
7043+
result in __security vulnerabilities__.
7044+
7045+
If you choose to use the `XStreamMarshaller` to unmarshal XML from an external source,
7046+
set the `supportedClasses` property on the `XStreamMarshaller`, like as follows:
70477047
70487048
[source,xml,indent=0]
70497049
[subs="verbatim,quotes"]

src/asciidoc/integration.adoc

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,21 @@ advanced and easier-to-use functionality. Refer to
388388
http://hc.apache.org/httpcomponents-client-ga/[hc.apache.org/httpcomponents-client-ga/]
389389
for more information.
390390

391+
[WARNING]
392+
====
393+
Be aware of vulnerabilities due to unsafe Java deserialization:
394+
Manipulated input streams could lead to unwanted code execution on the server
395+
during the deserialization step. As a consequence, do not expose HTTP invoker
396+
endpoints to untrusted clients but rather just between your own services.
397+
In general, we strongly recommend any other message format (e.g. JSON) instead.
398+
399+
If you are concerned about security vulnerabilities due to Java serialization,
400+
consider the general-purpose serialization filter mechanism at the core JVM level,
401+
originally developed for JDK 9 but backported to JDK 8, 7 and 6 in the meantime:
402+
https://blogs.oracle.com/java-platform-group/entry/incoming_filter_serialization_data_a
403+
http://openjdk.java.net/jeps/290
404+
====
405+
391406

392407

393408
[[remoting-httpinvoker-server]]
@@ -2560,15 +2575,15 @@ be obtained from JNDI instead (using `<jee:jndi-lookup>`). The Spring-based mess
25602575
listeners can then interact with the server-hosted `ResourceAdapter`, also using the
25612576
server's built-in `WorkManager`.
25622577

2563-
Please consult the JavaDoc for `JmsMessageEndpointManager`, `JmsActivationSpecConfig`,
2578+
Please consult the javadoc for `JmsMessageEndpointManager`, `JmsActivationSpecConfig`,
25642579
and `ResourceAdapterFactoryBean` for more details.
25652580

25662581
Spring also provides a generic JCA message endpoint manager which is not tied to JMS:
25672582
`org.springframework.jca.endpoint.GenericMessageEndpointManager`. This component allows
25682583
for using any message listener type (e.g. a CCI MessageListener) and any
25692584
provider-specific ActivationSpec object. Check out your JCA provider's documentation to
25702585
find out about the actual capabilities of your connector, and consult
2571-
`GenericMessageEndpointManager`'s JavaDoc for the Spring-specific configuration details.
2586+
`GenericMessageEndpointManager`'s javadoc for the Spring-specific configuration details.
25722587

25732588
[NOTE]
25742589
====
@@ -6028,7 +6043,6 @@ along with an inline image.
60286043

60296044
[WARNING]
60306045
====
6031-
60326046
Inline resources are added to the mime message using the specified `Content-ID` (
60336047
`identifier1234` in the above example). The order in which you are adding the text and
60346048
the resource are __very__ important. Be sure to __first add the text__ and after that

0 commit comments

Comments
 (0)