MASTG-KNOW-0021: Object Serialization
There are several ways to serialize an object on Android:
Java Serializable API¶
An object and its data can be represented as a sequence of bytes. This is done in Java viaobject serialization. Serialization is not inherently secure. It is just a binary format (or representation) for locally storing data in a .ser file. Encrypting and signing HMAC-serialized data is possible as long as the keys are stored safely. Deserializing an object requires a class of the same version as the class used to serialize the object. After classes have been changed, theObjectInputStream can't create objects from older .ser files. The example below shows how to create aSerializable class by implementing theSerializable interface.
importjava.io.Serializable;publicclassPersonimplementsSerializable{privateStringfirstName;privateStringlastName;publicPerson(StringfirstName,StringlastName){this.firstName=firstName;this.lastName=lastName;}//..//getters, setters, etc//..}Now you can read/write the object withObjectInputStream/ObjectOutputStream in another class.
JSON¶
There are several ways to serialize the contents of an object to JSON. Android comes with theJSONObject andJSONArray classes. A wide variety of libraries, includingGSON,Jackson,Moshi, can also be used. The main differences between the libraries are whether they use reflection to compose the object, whether they support annotations, whether the create immutable objects, and the amount of memory they use. Note that almost all the JSON representations are String-based and therefore immutable. This means that any secret stored in JSON will be harder to remove from memory.JSON itself can be stored anywhere, e.g., a (NoSQL) database or a file. You just need to make sure that any JSON that contains secrets has been appropriately protected (e.g., encrypted/HMACed). See the chapter"Data Storage on Android" for more details. A simple example (from the GSON User Guide) of writing and reading JSON with GSON follows. In this example, the contents of an instance of theBagOfPrimitives is serialized into JSON:
classBagOfPrimitives{privateintvalue1=1;privateStringvalue2="abc";privatetransientintvalue3=3;BagOfPrimitives(){// no-args constructor}}// SerializationBagOfPrimitivesobj=newBagOfPrimitives();Gsongson=newGson();Stringjson=gson.toJson(obj);// ==> json is {"value1":1,"value2":"abc"}XML¶
There are several ways to serialize the contents of an object to XML and back. Android comes with theXmlPullParser interface which allows for easily maintainable XML parsing. There are two implementations within Android:KXmlParser andExpatPullParser. TheAndroid Developer Guide provides a great write-up on how to use them. Next, there are various alternatives, such as aSAX parser that comes with the Java runtime. For more information, seea blogpost from ibm.com.Similarly to JSON, XML has the issue of working mostly String based, which means that String-type secrets will be harder to remove from memory. XML data can be stored anywhere (database, files), but do need additional protection in case of secrets or information that should not be changed. See the chapter "Data Storage on Android" for more details. As stated earlier: the true danger in XML lies in theXML eXternal Entity (XXE) attack as it might allow for reading external data sources that are still accessible within the application.
ORM¶
There are libraries that provide functionality for directly storing the contents of an object in a database and then instantiating the object with the database contents. This is called Object-Relational Mapping (ORM). Libraries that use the SQLite database include
Realm, on the other hand, uses its own database to store the contents of a class. The amount of protection that ORM can provide depends primarily on whether the database is encrypted. See the chapter"Data Storage on Android" for more details. The Realm website includes a niceexample of ORM Lite.
Parcelable¶
Parcelable is an interface for classes whose instances can be written to and restored from aParcel. Parcels are often used to pack a class as part of aBundle for anIntent. Here's an Android developer documentation example that implementsParcelable:
publicclassMyParcelableimplementsParcelable{privateintmData;publicintdescribeContents(){return0;}publicvoidwriteToParcel(Parcelout,intflags){out.writeInt(mData);}publicstaticfinalParcelable.Creator<MyParcelable>CREATOR=newParcelable.Creator<MyParcelable>(){publicMyParcelablecreateFromParcel(Parcelin){returnnewMyParcelable(in);}publicMyParcelable[]newArray(intsize){returnnewMyParcelable[size];}};privateMyParcelable(Parcelin){mData=in.readInt();}}Because this mechanism that involves Parcels and Intents may change over time, and theParcelable may containIBinder pointers, storing data to disk viaParcelable is not recommended.
Protocol Buffers¶
Protocol Buffers by Google, are a platform- and language neutral mechanism for serializing structured data by means of theBinary Data Format.There have been a few vulnerabilities with Protocol Buffers, such asCVE-2015-5237.Note that Protocol Buffers do not provide any protection for confidentiality: there is no built in encryption.