diff --git a/pippo-core/src/main/java/ro/pippo/core/Messages.java b/pippo-core/src/main/java/ro/pippo/core/Messages.java index 8405dbfcf..b1b6d3b0c 100644 --- a/pippo-core/src/main/java/ro/pippo/core/Messages.java +++ b/pippo-core/src/main/java/ro/pippo/core/Messages.java @@ -339,14 +339,16 @@ private Map loadRegisteredMessageResources(String name) { * Attempts to load a message resource. */ private Properties loadMessages(String fileOrUrl) { - URL url = ClasspathUtils.locateOnClasspath(fileOrUrl); - if (url != null) { - try (InputStreamReader reader = new InputStreamReader(url.openStream(), StandardCharsets.UTF_8)) { - Properties messages = new Properties(); - messages.load(reader); - return messages; - } catch (IOException e) { - log.error("Failed to load {}", fileOrUrl, e); + List urls = ClasspathUtils.getResources(fileOrUrl); + for (URL url: urls) { + if (url != null) { + try (InputStreamReader reader = new InputStreamReader(url.openStream(), StandardCharsets.UTF_8)) { + Properties messages = new Properties(); + messages.load(reader); + return messages; + } catch (IOException e) { + log.error("Failed to load {}", fileOrUrl, e); + } } } 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..375fd16d0 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 @@ -33,6 +33,7 @@ public class WhitelistObjectInputStream extends ObjectInputStream { private static List whiteClassNames; + private static List whitePackageNames; static { loadWhitelist(WhitelistObjectInputStream.class.getResourceAsStream(PippoConstants.LOCATION_OF_PIPPO_WHITELIST_SERIALIZATION)); @@ -44,7 +45,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)) && (!isWhiteListedPackageName(className))) { throw new InvalidClassException("Unauthorized deserialization attempt", className); } @@ -61,6 +62,16 @@ private boolean isWhiteListed(String className) { return false; } + private boolean isWhiteListedPackageName(String className) { + for (String packageName : whitePackageNames) { + if (className.startsWith(packageName)) { + return true; + } + } + + return false; + } + /** * Load the whitelist from an {@link InputStream}. * The content of the {@code InputStream} is in format: @@ -68,6 +79,9 @@ private boolean isWhiteListed(String className) { * # Java * java.util.ArrayList * java.util.HashMap + * # all class names in java.lang (please be aware of the trailing dot (.) aignalling that the whole package and + * # its sub-packages shall be whitelisted) + * 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 ends with a dot (.) whitelists a complete package and its sub-packages. */ 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.endsWith(".")) { + addWhitePackageName(line); } addWhiteClassName(line); @@ -101,4 +118,8 @@ private static void addWhiteClassName(String className) { whiteClassNames.add(className); } + private static void addWhitePackageName(String packageName) { + whitePackageNames.add(packageName); + } + }