iOS Serialisation and Encoding
OWASP’s object-serialization guidance provides additional code and testing context.[1]
Object Serialization in iOS Development
In iOS, object serialization converts objects into a representation that can be stored or transmitted and reconstructed later. NSCoding and NSSecureCoding support keyed archives for Objective-C-compatible object graphs, commonly producing Data/NSData; Swift value types commonly use Codable instead.[2][3]
NSCoding Implementation
To implement NSCoding, a class must inherit from NSObject or be marked as @objc. This protocol mandates the implementation of two methods for encoding and decoding instance variables:
class CustomPoint: NSObject, NSCoding {
var x: Double = 0.0
var name: String = ""
func encode(with aCoder: NSCoder) {
aCoder.encode(x, forKey: "x")
aCoder.encode(name, forKey: "name")
}
required convenience init?(coder aDecoder: NSCoder) {
guard let name = aDecoder.decodeObject(forKey: "name") as? String else { return nil }
self.init(x: aDecoder.decodeDouble(forKey: "x"), name: name)
}
}
Enhancing Security with NSSecureCoding
To reduce object-substitution attacks during unarchiving, NSSecureCoding requires callers to declare the expected classes and conforming classes to opt in. It improves type safety but does not encrypt or authenticate the archive, so untrusted or sensitive data may still require separate confidentiality and integrity controls.[2]
static var supportsSecureCoding: Bool {
return true
}
let obj = decoder.decodeObject(of: MyClass.self, forKey: "myKey")
Data Archiving with NSKeyedArchiver
NSKeyedArchiver and NSKeyedUnarchiver encode and decode object graphs. The following legacy APIs illustrate older code that may still appear during review, but Apple deprecated them; new code should use secure archiving/unarchiving APIs that specify the expected root class.[3]
NSKeyedArchiver.archiveRootObject(customPoint, toFile: "/path/to/archive")
let customPoint = NSKeyedUnarchiver.unarchiveObjectWithFile("/path/to/archive") as? CustomPoint
Using Codable for Simplified Serialization
Swift’s Codable protocol combines Decodable and Encodable, facilitating the encoding and decoding of objects like String, Int, Double, etc., without extra effort:
struct CustomPointStruct: Codable {
var x: Double
var name: String
}
This approach supports straightforward serialization to and from property lists and JSON.[4]
JSON and XML Encoding Alternatives
Beyond native support, several third-party libraries offer JSON and XML encoding/decoding capabilities, each with its own performance characteristics and security considerations. It’s imperative to carefully select these libraries, especially to mitigate vulnerabilities like XXE (XML External Entities) attacks by configuring parsers to prevent external entity processing.
Security Considerations
When serializing data, especially to the file system, it’s essential to be vigilant about the potential inclusion of sensitive information. Serialized data, if intercepted or improperly handled, can expose applications to risks such as unauthorized actions or data leakage. Encrypting and signing serialized data is recommended to enhance security.