Log Message
Merge fix for security vulnerability from HEAD.
Modified Paths
- branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/converters/reflection/ReflectionConverter.java
- branches/v-1.4.x/xstream-distribution/src/content/changes.html
- branches/v-1.4.x/xstream-distribution/src/content/faq.html
Added Paths
Property Changed
Diff
Property changes: branches/v-1.4.x
Modified: svn:mergeinfo
Modified: branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/converters/reflection/ReflectionConverter.java (2197 => 2198)
--- branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/converters/reflection/ReflectionConverter.java 2013-12-23 14:44:10 UTC (rev 2197)
+++ branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/converters/reflection/ReflectionConverter.java 2013-12-23 14:48:50 UTC (rev 2198)
@@ -11,15 +11,33 @@
*/
package com.thoughtworks.xstream.converters.reflection;
+import java.beans.EventHandler;
+
import com.thoughtworks.xstream.mapper.Mapper;
public class ReflectionConverter extends AbstractReflectionConverter {
+ private Class type;
+
public ReflectionConverter(Mapper mapper, ReflectionProvider reflectionProvider) {
super(mapper, reflectionProvider);
}
+ /**
+ * Construct a ReflectionConverter for an explicit type.
+ *
+ * @param mapper the mapper in use
+ * @param reflectionProvider the reflection provider in use
+ * @param type the explicit type to handle
+ * @since upcoming
+ */
+ public ReflectionConverter(Mapper mapper, ReflectionProvider reflectionProvider, Class type) {
+ this(mapper, reflectionProvider);
+ this.type = type;
+ }
+
public boolean canConvert(Class type) {
- return type != null && canAccess(type);
+ return ((this.type != null && this.type == type) || (this.type == null && type != null && type != EventHandler.class))
+ && canAccess(type);
}
}
Copied: branches/v-1.4.x/xstream/src/test/com/thoughtworks/acceptance/SecurityVulnerabilityTest.java (from rev 2197, trunk/xstream/src/test/com/thoughtworks/acceptance/SecurityVulnerabilityTest.java) (0 => 2198)
--- branches/v-1.4.x/xstream/src/test/com/thoughtworks/acceptance/SecurityVulnerabilityTest.java (rev 0)
+++ branches/v-1.4.x/xstream/src/test/com/thoughtworks/acceptance/SecurityVulnerabilityTest.java 2013-12-23 14:48:50 UTC (rev 2198)
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2013 XStream Committers.
+ * All rights reserved.
+ *
+ * The software in this package is published under the terms of the BSD
+ * style license a copy of which has been included with this distribution in
+ * the LICENSE.txt file.
+ *
+ * Created on 23. December 2013 by Joerg Schaible
+ */
+package com.thoughtworks.acceptance;
+
+import java.beans.EventHandler;
+
+import com.thoughtworks.xstream.XStreamException;
+import com.thoughtworks.xstream.converters.ConversionException;
+import com.thoughtworks.xstream.converters.reflection.ReflectionConverter;
+
+/**
+ * @author Jörg Schaible
+ */
+public class SecurityVulnerabilityTest extends AbstractAcceptanceTest {
+
+ private final static StringBuffer BUFFER = new StringBuffer();
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ BUFFER.setLength(0);
+ }
+
+ public void testCannotInjectEventHandler() {
+ String xml = ""
+ + "<string class='set'>\n"
+ + " <dynamic-proxy>\n"
+ + " <interface>java.lang.Comparable</interface>\n"
+ + " <handler class='java.beans.EventHandler'>\n"
+ + " <target class='com.thoughtworks.acceptance.SecurityVulnerabilityTest$Run'/>\n"
+ + " <action>run</action>\n"
+ + " </handler>\n"
+ + " </dynamic-proxy>\n"
+ + "</string>";
+
+ try {
+ xstream.fromXML(xml);
+ fail("Thrown " + XStreamException.class.getName() + " expected");
+ } catch (final XStreamException e) {
+ assertTrue(e.getMessage().contains(EventHandler.class.getName()));
+ }
+ assertEquals(0, BUFFER.length());
+ }
+
+ public void testExplicitlyConvertEventHandler() {
+ String xml = ""
+ + "<string class='tree-set'>\n"
+ + " <dynamic-proxy>\n"
+ + " <interface>java.lang.Comparable</interface>\n"
+ + " <handler class='java.beans.EventHandler'>\n"
+ + " <target class='com.thoughtworks.acceptance.SecurityVulnerabilityTest$Run'/>\n"
+ + " <action>run</action>\n"
+ + " </handler>\n"
+ + " </dynamic-proxy>\n"
+ + " <object/>\n"
+ + "</string>";
+
+ xstream.registerConverter(new ReflectionConverter(xstream.getMapper(), xstream
+ .getReflectionProvider(), EventHandler.class));
+ try {
+ xstream.fromXML(xml);
+ fail("Thrown " + ConversionException.class.getName() + " expected");
+ } catch (final ConversionException e) {
+ assertEquals(NullPointerException.class, e.getCause().getClass());
+ }
+
+ assertEquals("Did run!", BUFFER.toString());
+ }
+
+ public static class Run implements Runnable {
+
+ public void run() {
+ BUFFER.append("Did run!");
+ }
+ }
+}
Modified: branches/v-1.4.x/xstream-distribution/src/content/changes.html (2197 => 2198)
--- branches/v-1.4.x/xstream-distribution/src/content/changes.html 2013-12-23 14:44:10 UTC (rev 2197)
+++ branches/v-1.4.x/xstream-distribution/src/content/changes.html 2013-12-23 14:48:50 UTC (rev 2198)
@@ -35,14 +35,23 @@
<h2>Major changes</h2>
<ul>
+ <li>java.bean.EventHandler no longer handled automatically because of severe security vulnerability.</li>
</ul>
<h2>Minor changes</h2>
<ul>
<li>XSTR-749: NPE if ReflectionConverter.canConvert(type) is called with null as argument.</li>
+ <li>Add constructor to ReflectionConverter taking an additional type to create an instance that is
+ dedicated to a specific type only.</li>
</ul>
+ <h2>API changes</h2>
+
+ <ul>
+ <li>Added c.t.x.converters.reflection.ReflectionConverter(Mapper,ReflectionProvider,Class).</li>
+ </ul>
+
<h1 id="1.4.6">1.4.6</h1>
<p>Released December 12, 2013.</p>
Modified: branches/v-1.4.x/xstream-distribution/src/content/faq.html (2197 => 2198)
--- branches/v-1.4.x/xstream-distribution/src/content/faq.html 2013-12-23 14:44:10 UTC (rev 2197)
+++ branches/v-1.4.x/xstream-distribution/src/content/faq.html 2013-12-23 14:48:50 UTC (rev 2198)
@@ -21,6 +21,7 @@
<li><a href=""
<li><a href="" specifics</a></li>
<li><a href="" specifics</a></li>
+ <li><a href="" aspects</a></li>
<li><a href="" to other products</a></li>
<li><a href=""
<li><a href="" of XStream</a></li>
@@ -407,8 +408,8 @@
<p>XStream architecture is based on IO Readers and Writers, while the XML declaration is the responsibility of XML
parsers. All <a href=""
implementations respect the encoding since version 1.3, but only if you provide an
- <a href="" If XStream consumes a
- <a href="" you have to initialize the reader with
+ <a href="" If XStream consumes a
+ <a href="" you have to initialize the reader with
the appropriate encoding yourself, since it is now the reader's task to perform the encoding and no XML parser can
change the encoding of a Reader and any encoding definition in the XML header will be ignored.</p>
@@ -423,7 +424,7 @@
<p>XStream does no character encoding by itself, it relies on the configuration of the underlying XML writer.
By default it uses its own PrettyPrintWriter which writes into the default encoding of the current locale. To write
- UTF-8 you have to provide a <a href=""
+ UTF-8 you have to provide a <a href=""
with the appropriate encoding yourself.</p>
<!-- ...................................................... -->
@@ -502,7 +503,7 @@
<h2 id="XML_xpath_nodelist">The XPath expressions in the references do select a list, but not a single node!</h2>
<p>Yes, this is right. However, the result type of an
- <a href="" _expression_</a>
+ <a href="" _expression_</a>
evaluation can be defined. A node result from a node list is the lists first node, therefore the XPath of XStream
is compliant. Since XStream does not use a real XPath engine, you do not have to worry about memory consumption or
wasted evaluation time, XStream will always operate on a single node anyway. Since XStream 1.4 you can force
@@ -515,6 +516,7 @@
<!-- ****************************************************** -->
<h1 id="JSON">JSON specifics</h1>
+ <!-- ...................................................... -->
<h2 id="JSON_2_drivers">Why are there two JSON driver implementations?</h2>
<p>As always, first for historical reasons! Main difference is that the
@@ -524,17 +526,20 @@
<a href=""
uses an own more flexible implementation, but can only be used to generate JSON, deserialization is not implemented.</p>
+ <!-- ...................................................... -->
<h2 id="JSON_Jettison_version">Which versions of Jettison are supported?</h2>
<p>Users of Java 5 or higher can use Jettison 1.2, users of Java 1.4.2 have to use Jettison 1.0.1. Jettison 1.1
nor Jettison 1.3 or higher is supported.</p>
+ <!-- ...................................................... -->
<h2 id="JSON_deserialize_top_level_array">Why is it not possible to deserialize a JSON string starting with an array?</h2>
<p>XStream's implementation to deserialize JSON is based on Jettison and StAX. Jettison implements a XMLStreamReader
of StaX and transforms the processed JSON virtually into XML first. However, if the JSON string starts with an array it is not
possible for Jettison to create a valid root element, since it has no name.</p>
+ <!-- ...................................................... -->
<h2 id="JSON_unmarshalling_fails">XStream fails to unmarshal my JSON string and I do not know why?</h2>
<p>Deserialization of JSON is currently done by Jettison, that transforms the JSON string into a StAX stream.
@@ -554,6 +559,7 @@
System.out.println(writer.toString());
</pre></div>
+ <!-- ...................................................... -->
<h2 id="JSON_limitations">What limitations has XStream's JSON support?</h2>
<p>JSON represents a very simple data model for easy data transfer. Especially it has no equivalent for XML
@@ -563,6 +569,7 @@
possibility to express such a construct. You should therefore always set the NO_REFERENCES mode of XStream.
Additionally you cannot use implicit collections, since the properties in a JSON object must have unique names.</p>
+ <!-- ...................................................... -->
<h2 id="JSON_JavaScript_Long">Why are my Long values incorrect in _javascript_?</h2>
<p>_javascript_ does not know about integer values. All numbers are represented with double precition floats using
@@ -575,12 +582,14 @@
<strong>jettison.mapped.typeconverter.enforce_32bit_integer</strong> to <strong>true</strong> (not available for
Jettison 1.0.1 and Java 1.4).</p>
+ <!-- ...................................................... -->
<h2 id="JSON_encoding">Why are there invalid characters in my JSON representation?</h2>
<p>The JSON spec requires any JSON string to be in UTF-8 encoding. However, XStream ensures this only if you
provide an InputStream or an OutputStream. If you provide a Reader or Writer you have to ensure this requirement
on your own.</p>
+ <!-- ...................................................... -->
<h2 id="JSON_dashes">The generated JSON is invalid, it contains a dash in the label!</h2>
<p>Well, no, the JSON is valid! Please check yourself with the <a href="" syntax checker</a>.
@@ -610,13 +619,43 @@
</pre></div>
<!-- ****************************************************** -->
+ <h1 id="Security">Security Aspects</h1>
+
+ <!-- ...................................................... -->
+ <h2 id="Security_EventHandler">Why does XStream not convert an java.beans.EventHandler?</h2>
+
+ <p>Since XStream verison 1.4.7 it does no longer handle an
+ <a href="" automatically.
+ Such an instance can be used to initiate calls on arbitray instances at deserialization time e.g.
+ <a href=""
+ You can register a ReflectionConverter instance explicitly for the EventHandler if you need support for such
+ instances.</p>
+
+ <!-- ...................................................... -->
+ <h2 id="Security_ArbitraryDeserialization">XStream deserializes arbitrary objects!</h2>
+
+ <p>Yes, XStream is designed to convert any object form Java to XML and back out of the box. In consequence it is
+ possible to adjust the processed XML manually to inject arbitrary objects into the deserialized object graph. To
+ avoid such a behavior, you have several options:</p>
+
+ <ul>
+ <li>Prevent the usage of the reflection-based converters. Register an own converter with priority LOW that claims
+ to handle any type and throw a ConversionException in the marshal and unmarshal methods.</li>
+ <li>Overload XStream.setupConverters() and register only converters for the types that are allowd in your object
+ graph.</li>
+ <li>Provide own implementations for ConverterLookup and ConverterRegistry constructing the XStream. Your
+ implementation can then select the appropriate converter at lookup time on its own or prevent the registration of
+ specific converters.</li>
+ </ul>
+
+ <!-- ****************************************************** -->
<h1 id="Other_Products">Comparison to other products</h1>
<!-- ...................................................... -->
<h2 id="Other_Products_XMLBeanEncoder">How does XStream compare to java.beans.XMLEncoder?</h2>
<p>XStream is designed for serializing <i>objects</i> using internal fields, whereas
- <a href="" is designed for
+ <a href="" is designed for
serializing <i>JavaBeans</i> using public API methods (typically in the form
of <code>getXXX()</code>, <code>setXXX()</code>, <code>addXXX()</code> and <code>removeXXX()</code> methods.</p>
@@ -626,34 +665,6 @@
XML matching the processed schema and back. Note, that you cannot use your own objects, you have to use what is
generated.</p>
- <!--
- <h1>Comparison to other products</h1>
-
- <h2>How does XStream compare to JAXB (Java API for XML Binding)?</h2>
- <p>Todo...</p>
-
- <h2>How does XStream compare to JSX?</h2>
- <p>Todo...</p>
-
- <h2>How does XStream compare to Betwixt?</h2>
- <p>Todo...</p>
-
- <h2>How does XStream compare to Castor?</h2>
- <p>Todo...</p>
-
- <h2>How does XStream compare to Electric XML?</h2>
- <p>Todo...</p>
-
- <h2>How does XStream compare to JOX?</h2>
- <p>Todo...</p>
-
- <h2>How does XStream compare to JIBX?</h2>
- <p>Todo...</p>
-
- -->
-
-
-
<!-- ****************************************************** -->
<h1 id="Scalability">Scalability</h1>
To unsubscribe from this list please visit:
