diff --git a/pippo-content-type-parent/pippo-xstream/pom.xml b/pippo-content-type-parent/pippo-xstream/pom.xml
index 0f3c4d303..a42363993 100644
--- a/pippo-content-type-parent/pippo-xstream/pom.xml
+++ b/pippo-content-type-parent/pippo-xstream/pom.xml
@@ -15,7 +15,7 @@
XStream integration
- 1.4.9
+ 1.4.11.1
diff --git a/pippo-content-type-parent/pippo-xstream/src/main/java/ro/pippo/xstream/XstreamEngine.java b/pippo-content-type-parent/pippo-xstream/src/main/java/ro/pippo/xstream/XstreamEngine.java
index f4e6788a5..2922c1209 100644
--- a/pippo-content-type-parent/pippo-xstream/src/main/java/ro/pippo/xstream/XstreamEngine.java
+++ b/pippo-content-type-parent/pippo-xstream/src/main/java/ro/pippo/xstream/XstreamEngine.java
@@ -21,6 +21,9 @@
import ro.pippo.core.HttpConstants;
import com.thoughtworks.xstream.XStream;
+import ro.pippo.core.util.WhitelistObjectInputStream;
+
+import java.util.regex.Pattern;
/**
* An XmlEngine based on XStream.
@@ -45,6 +48,10 @@ private XStream xstream() {
xstream.autodetectAnnotations(true);
// prevent xstream from creating complex XML graphs
xstream.setMode(XStream.NO_REFERENCES);
+
+ //setup security
+ xstream.allowTypes((String[]) WhitelistObjectInputStream.getWhitelistedClassNames().toArray());
+ xstream.allowTypesByRegExp((Pattern[]) WhitelistObjectInputStream.getWhitelistedRegExp().toArray());
return xstream;
}
diff --git a/pippo-core/src/main/java/ro/pippo/core/util/WhitelistObjectInputStream.java b/pippo-core/src/main/java/ro/pippo/core/util/WhitelistObjectInputStream.java
index 6b05ef6dc..8d3ae6f00 100644
--- a/pippo-core/src/main/java/ro/pippo/core/util/WhitelistObjectInputStream.java
+++ b/pippo-core/src/main/java/ro/pippo/core/util/WhitelistObjectInputStream.java
@@ -24,6 +24,7 @@
import java.io.ObjectStreamClass;
import java.util.ArrayList;
import java.util.List;
+import java.util.regex.Pattern;
/**
* When deserializing objects, first check that the class being deserialized is in the allowed whitelist.
@@ -33,6 +34,7 @@
public class WhitelistObjectInputStream extends ObjectInputStream {
private static List whiteClassNames;
+ private static List whiteRegExp;
static {
loadWhitelist(WhitelistObjectInputStream.class.getResourceAsStream(PippoConstants.LOCATION_OF_PIPPO_WHITELIST_SERIALIZATION));
@@ -44,7 +46,7 @@ public WhitelistObjectInputStream(InputStream in) throws IOException {
protected Class> resolveClass(ObjectStreamClass descriptor) throws ClassNotFoundException, IOException {
String className = descriptor.getName();
- if (!isWhiteListed(className)) {
+ if ((!isWhiteListed(className)) && (!isWhiteListedRegex(className))) {
throw new InvalidClassException("Unauthorized deserialization attempt", className);
}
@@ -61,6 +63,16 @@ private boolean isWhiteListed(String className) {
return false;
}
+ private boolean isWhiteListedRegex(String className) {
+ for (Pattern pattern : whiteRegExp) {
+ if (pattern.matcher(className).matches()) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
/**
* Load the whitelist from an {@link InputStream}.
* The content of the {@code InputStream} is in format:
@@ -68,6 +80,8 @@ private boolean isWhiteListed(String className) {
* # Java
* java.util.ArrayList
* java.util.HashMap
+ * A regular expression whitelisting the whole java.lang package and its sub-packages.
+ * /java.lang.* /
*
* # Pippo
* ro.pippo.session.DefaultSessionData
@@ -75,6 +89,7 @@ private boolean isWhiteListed(String className) {
* }
*
* A line that starts with {@code #} is a comment and will be ignored.
+ * A line that starts and ends with {@code /} is interpreted as a regular expression.
*/
private static void loadWhitelist(InputStream input) {
String content;
@@ -91,6 +106,8 @@ private static void loadWhitelist(InputStream input) {
if (line.startsWith("#")) {
// it's a comment; ignore line
continue;
+ } else if (line.startsWith("/") && (line.endsWith("/"))) {
+ addWhiteRegExp(Pattern.compile(line.substring(1, line.length() - 2)));
}
addWhiteClassName(line);
@@ -101,4 +118,24 @@ private static void addWhiteClassName(String className) {
whiteClassNames.add(className);
}
+ private static void addWhiteRegExp(Pattern pattern) {
+ whiteRegExp.add(pattern);
+ }
+
+ /**
+ * Returns the whitelisted class names.
+ * @return the whitelisted class names.
+ */
+ public static List getWhitelistedClassNames() {
+ return whiteClassNames;
+ }
+
+ /**
+ * Returns the whitelisted regular expressions.
+ * @return the whitelisted regular expressions.
+ */
+ public static List getWhitelistedRegExp() {
+ return whiteRegExp;
+ }
+
}