]> gitweb.fperrin.net Git - Dictionary.git/commitdiff
Add whitelist for deserialization.
authorReimar Döffinger <Reimar.Doeffinger@gmx.de>
Tue, 15 Dec 2015 06:17:22 +0000 (07:17 +0100)
committerReimar Döffinger <Reimar.Doeffinger@gmx.de>
Tue, 15 Dec 2015 06:17:22 +0000 (07:17 +0100)
src/com/hughes/android/dictionary/DictionaryApplication.java
src/com/hughes/android/util/PersistentObjectCache.java

index a94ed53736425dbf36713aa2a026527b66fb3121..d73d6138e7ec519481830283cdc45e02c10d63d9 100644 (file)
@@ -276,7 +276,7 @@ public class DictionaryApplication extends Application {
 
     }
 
-    static final class DictionaryConfig implements Serializable {
+    public static final class DictionaryConfig implements Serializable {
         private static final long serialVersionUID = -1444177164708201263L;
         // User-ordered list, persisted, just the ones that are/have been
         // present.
index 150e3e6d75b545b4d22e937eaf427d84471acf0b..56c546e9d5a869da25e712e6a4e8897c718d6c2c 100644 (file)
@@ -18,12 +18,21 @@ import android.content.Context;
 import android.os.Environment;
 import android.util.Log;
 
+import com.hughes.android.dictionary.DictionaryApplication;
+import com.hughes.android.dictionary.DictionaryInfo;
+
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InvalidClassException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
+import java.io.ObjectStreamClass;
 import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.Map;
 
@@ -32,6 +41,29 @@ public class PersistentObjectCache {
     private final File dir;
     private final Map<String, Object> objects = new LinkedHashMap<String, Object>();
 
+    class ConstrainedOIS extends ObjectInputStream {
+      public ConstrainedOIS(InputStream in) throws IOException {
+        super(in);
+      }
+
+      protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
+        String name = desc.getName();
+        // Note: try to avoid adding more classes.
+        // LinkedHashMap is already more than enough for a DoS
+        if (!name.equals(ArrayList.class.getName()) &&
+            !name.equals(HashMap.class.getName()) &&
+            !name.equals(LinkedHashMap.class.getName()) &&
+            !name.equals(String.class.getName()) &&
+            !name.equals(DictionaryApplication.DictionaryConfig.class.getName()) &&
+            !name.equals(DictionaryInfo.class.getName()) &&
+            !name.equals(DictionaryInfo.IndexInfo.class.getName()))
+        {
+          throw new InvalidClassException("Not allowed to deserialize class", name);
+        }
+        return super.resolveClass(desc);
+      }
+    }
+
     public synchronized <T extends Serializable> T read(final String filename, final Class<T> resultClass) {
         try {
             Object object = (objects.get(filename));
@@ -45,7 +77,7 @@ public class PersistentObjectCache {
                 return null;
             }
             try {
-                final ObjectInputStream in = new ObjectInputStream(new FileInputStream(src));
+                final ObjectInputStream in = new ConstrainedOIS(new FileInputStream(src));
                 object = in.readObject();
                 in.close();
             } catch (Exception e) {