Hacktricks-skills ios-serialization-security
Security testing for iOS object serialization vulnerabilities. Use this skill whenever testing iOS apps for insecure deserialization, NSCoding/NSSecureCoding issues, NSKeyedArchiver/Unarchiver abuse, or Codable implementation flaws. Trigger when the user mentions iOS serialization, archiving, object persistence, NSCoder, or any iOS data encoding security concerns.
git clone https://github.com/abelrguezr/hacktricks-skills
skills/mobile-pentesting/ios-pentesting/ios-serialisation-and-encoding/SKILL.MDiOS Serialization Security Testing
This skill helps you identify and exploit serialization vulnerabilities in iOS applications. Serialization vulnerabilities can lead to arbitrary code execution, data leakage, and privilege escalation.
Understanding iOS Serialization
iOS provides multiple serialization mechanisms, each with distinct security implications:
- NSCoding: Basic serialization protocol (insecure by default)
- NSSecureCoding: Enhanced type-safe serialization (still not encrypted)
- NSKeyedArchiver/Unarchiver: File-based object persistence
- Codable: Modern Swift serialization (generally safer)
- JSON/XML: Text-based formats with their own risks
Testing NSCoding Vulnerabilities
Check for NSCoding Implementation
Look for classes implementing
NSCoding without NSSecureCoding:
// Insecure - vulnerable to class substitution attacks @interface VulnerableClass : NSObject <NSCoding> @end // Secure - requires type checking during decoding @interface SecureClass : NSObject <NSSecureCoding> @end
What to look for:
- Classes with
but missingNSCodingNSSecureCoding - Missing
property set tosupportsSecureCodingYES - Use of
instead ofdecodeObject:decodeObject(of:forKey:)
Exploitation Technique
When
NSSecureCoding is not enforced, attackers can substitute classes during deserialization:
- Identify the serialized data format (usually in app's Documents or Library directories)
- Modify the class name in the archive to point to a malicious class
- Trigger deserialization to execute arbitrary code
Testing NSKeyedArchiver/Unarchiver
Locate Archived Data
Search for archived files in common locations:
# In jailbroken device or simulator find ~/Documents -name "*.archive" -o -name "*.dat" -o -name "*.plist" find ~/Library -name "*.archive" -o -name "*.dat"
Test for Insecure Unarchiving
Check if the app uses deprecated or insecure unarchiving methods:
// Insecure - deprecated [NSKeyedUnarchiver unarchiveObjectWithFile:@"path"]; // Secure - requires secure coding [NSKeyedUnarchiver unarchiveObjectOfClasses:allowedClasses fromData:data];
Red flags:
- Use of
orunarchiveObjectWithFile:unarchiveObjectWithData: - No class whitelist validation
- Deserializing data from untrusted sources (network, user input)
Testing Codable Implementation
Review Codable Conformance
// Generally safe - type-safe by default struct SafeData: Codable { let id: Int let name: String } // Potential issues - custom decoding struct CustomData: Codable { let data: Data enum CodingKeys: String, CodingKey { case data } init(from decoder: Decoder) throws { // Check for custom logic that might be vulnerable } }
What to check:
- Custom
implementations with unsafe operationsinit(from:) - Decoding of
types that might contain serialized objectsData - Use of
on classes that might be subclassedDecodable
Security Testing Checklist
Static Analysis
-
Search for serialization keywords:
grep -r "NSCoding" app_source/ grep -r "NSSecureCoding" app_source/ grep -r "NSKeyedArchiver" app_source/ grep -r "NSKeyedUnarchiver" app_source/ grep -r "Codable" app_source/ -
Check for secure coding enforcement:
grep -r "supportsSecureCoding" app_source/ grep -r "decodeObject(of:" app_source/ -
Identify data sources:
- Network responses being deserialized
- Files from user downloads
- Shared preferences or keychain data
Dynamic Analysis
-
Hook deserialization methods:
// Using Frida const NSKeyedUnarchiver = ObjC.classes.NSKeyedUnarchiver; NSKeyedUnarchiver.unarchiveObjectWithData.implementation = function(data) { console.log("Unarchiving data:", data); return this.unarchiveObjectWithData(data); }; -
Monitor file access:
- Track reads from Documents/Library directories
- Identify archived files being loaded
-
Test with modified archives:
- Create malicious archives with substituted classes
- Attempt to trigger deserialization
Common Vulnerable Patterns
Pattern 1: Insecure Class Substitution
// Vulnerable code - (id)initWithCoder:(NSCoder *)aDecoder { self = [super init]; if (self) { self.object = [aDecoder decodeObjectForKey:@"object"]; // No type check! } return self; }
Exploitation: Replace the expected class with a malicious subclass that executes code in
init.
Pattern 2: Untrusted Data Deserialization
// Vulnerable - deserializing network data func handleResponse(data: Data) { let object = NSKeyedUnarchiver.unarchiveObject(with: data) as? MyObject // Process object without validation }
Exploitation: Send crafted serialized data over the network.
Pattern 3: Missing Secure Coding Flag
// Vulnerable - NSCoding without NSSecureCoding @interface MyModel : NSObject <NSCoding> @end @implementation MyModel - (void)encodeWithCoder:(NSCoder *)aCoder { [aCoder encodeObject:self.data forKey:@"data"]; } @end
Exploitation: Same as Pattern 1 - class substitution attacks.
Mitigation Recommendations
For Developers
-
Always use NSSecureCoding:
@interface SecureModel : NSObject <NSSecureCoding> @end @implementation SecureModel + (BOOL)supportsSecureCoding { return YES; } - (id)initWithCoder:(NSCoder *)aDecoder { self = [super init]; if (self) { self.data = [aDecoder decodeObjectOfClass:[NSData class] forKey:@"data"]; } return self; } @end -
Prefer Codable for new code:
struct SafeModel: Codable { let id: UUID let name: String } -
Validate data sources:
- Never deserialize untrusted data
- Use JSON for external data exchange
- Sign and verify serialized data
-
Encrypt sensitive data:
- Serialization is not encryption
- Use Keychain for sensitive values
- Encrypt archived data at rest
References
Quick Commands
# Find all NSCoding implementations grep -r "<NSCoding>" . --include="*.m" --include="*.swift" # Find unarchiver usage grep -r "unarchiveObject" . --include="*.m" --include="*.swift" # Check for secure coding grep -r "supportsSecureCoding" . --include="*.m" --include="*.swift" # List archived files in app container find ~/Library/Containers/com.example.app/Data/Documents -type f
When to Use This Skill
Use this skill when:
- Testing iOS apps for deserialization vulnerabilities
- Reviewing iOS code for serialization security
- Investigating data persistence mechanisms in iOS
- Analyzing archived files from iOS applications
- Assessing NSCoder/NSKeyedArchiver implementations
- Evaluating Codable implementations for security issues
This skill provides the methodology and patterns needed to identify and exploit iOS serialization vulnerabilities during mobile security assessments.