package org.schabi.newpipe.settings.export; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectStreamClass; import java.util.Set; /** * An {@link ObjectInputStream} that only allows preferences-related types to be deserialized, to * prevent injections. The only allowed types are: all primitive types, all boxed primitive types, * null, strings. HashMap, HashSet and arrays of previously defined types are also allowed. Sources: * * cmu.edu * , * * OWASP cheatsheet * , * * Apache's {@code ValidatingObjectInputStream} * */ public class PreferencesObjectInputStream extends ObjectInputStream { /** * Primitive types, strings and other built-in types do not pass through resolveClass() but * instead have a custom encoding; see * * official docs. */ private static final Set CLASS_WHITELIST = Set.of( "java.lang.Boolean", "java.lang.Byte", "java.lang.Character", "java.lang.Short", "java.lang.Integer", "java.lang.Long", "java.lang.Float", "java.lang.Double", "java.lang.Void", "java.util.HashMap", "java.util.HashSet" ); public PreferencesObjectInputStream(final InputStream in) throws IOException { super(in); } @Override protected Class resolveClass(final ObjectStreamClass desc) throws ClassNotFoundException, IOException { if (CLASS_WHITELIST.contains(desc.getName())) { return super.resolveClass(desc); } else { throw new ClassNotFoundException("Class not allowed: " + desc.getName()); } } }