Skip to content

Commit

Permalink
Improved: Improve ObjectInputStream denyList (OFBIZ-12221)
Browse files Browse the repository at this point in the history
In SafeObjectInputStream.properties
  Renames listOfSafeObjectsForInputStream to allowList and fixes it
  Introduces a denyList

Adapts SafeObjectInputStream class to new denyList
  • Loading branch information
JacquesLeRoux committed Apr 7, 2021
1 parent fcc0078 commit 3f97578
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 13 deletions.
19 changes: 12 additions & 7 deletions framework/base/config/SafeObjectInputStream.properties
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,18 @@
# under the License.
###############################################################################

# Because of OFBIZ-10837 - Improve ObjectInputStream class.
# If you encounter a related issue (object not in the allowlist),
# you must provide a complete list of objects to pass to ObjectInputStream
# through ListOfSafeObjectsForInputStream property
# As an example, the a complete list of objects used by OFBiz OOTB is here.
# Because of OFBIZ-10837 "Improve ObjectInputStream class."
# If you encounter a related issue (object not in the allowList),
# you must provide a complete list of objects to pass to ObjectInputStream through allowList property
# As an example, the a complete list of objects used by OFBiz OOTB is here in allowList.
# You will need to add your objects/classes to this list.
# OFBiz committers: don't forget to add newobjects in SafeObjectInputStream class too (as default there).

# OFBiz committers:
# . don't forget to add new objects in SafeObjectInputStream class too (as default there).
# . "foo" and "SerializationInjector" are used in OFBiz tests

listOfSafeObjectsForInputStream=byte\\\\[\\\\], foo, SerializationInjector, \\\\[Z,\\\\[B,\\\\[S,\\\\[I,\\\\[J,\\\\[F,\\\\[D,\\\\[C, java..*, sun.util.calendar..*, org.apache.ofbiz..*, org.codehaus.groovy.runtime.GStringImpl, groovy.lang.GString
allowList=byte\\[\\], foo, SerializationInjector, \\[Z,\\[B,\\[S,\\[I,\\[J,\\[F,\\[D,\\[C, java..*, sun.util.calendar..*, org.apache.ofbiz..*, org.codehaus.groovy.runtime.GStringImpl, groovy.lang.GString

#-- List of strings rejected for serialisation
#-- The same comments than for allowList apply to denyList
denyList=rmi, <
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public final class SafeObjectInputStream extends ObjectInputStream {
"\\[Z", "\\[B", "\\[S", "\\[I", "\\[J", "\\[F", "\\[D", "\\[C",
"java..*", "sun.util.calendar..*", "org.apache.ofbiz..*",
"org.codehaus.groovy.runtime.GStringImpl", "groovy.lang.GString"};
private static final String[] DEFAULT_DENYLIST = { "rmi", "<" };

/** The regular expression used to match serialized types. */
private final Pattern allowlistPattern;
Expand All @@ -53,9 +54,9 @@ public final class SafeObjectInputStream extends ObjectInputStream {
*/
public SafeObjectInputStream(InputStream in) throws IOException {
super(in);
String safeObjectsProp = getPropertyValue("SafeObjectInputStream", "ListOfSafeObjectsForInputStream", "");
String[] allowlist = safeObjectsProp.isEmpty() ? DEFAULT_ALLOWLIST_PATTERN : safeObjectsProp.split(",");
allowlistPattern = Arrays.stream(allowlist)
String allowListProp = getPropertyValue("SafeObjectInputStream", "allowList", "");
String[] allowList = allowListProp.isEmpty() ? DEFAULT_ALLOWLIST_PATTERN : allowListProp.split(",");
allowlistPattern = Arrays.stream(allowList)
.map(String::trim)
.filter(str -> !str.isEmpty())
.collect(collectingAndThen(joining("|", "(", ")"), Pattern::compile));
Expand All @@ -65,9 +66,13 @@ public SafeObjectInputStream(InputStream in) throws IOException {
protected Class<?> resolveClass(ObjectStreamClass classDesc) throws IOException, ClassNotFoundException {
String className = classDesc.getName();
// DenyList
if (className.contains("java.rmi") // Don't allow RMI
|| className.contains("<")) { // Prevent generics markup in string type names
throw new InvalidClassException(className, "Unauthorized deserialisation attempt");
String rejectedObjectsProp = getPropertyValue("security", "denyList", "");
String[] denyList = rejectedObjectsProp.isEmpty() ? DEFAULT_DENYLIST : rejectedObjectsProp.split(",");
// For now DEFAULT_DENYLIST: don't allow RMI, prevent generics markup in string type names
for (String deny : denyList) {
if (className.contains(deny)) {
throw new InvalidClassException(className, "Unauthorized deserialisation attempt");
}
}
if (!allowlistPattern.matcher(className).find()) {
Debug.logWarning("***Incompatible class***: " + className
Expand Down

0 comments on commit 3f97578

Please sign in to comment.