lcimeni / tiktok-ios

0 stars 0 forks source link

NowSecure dynamic analysis: Use of Unsafe Serialization API Exposes App to Remote Code Execution #71

Open lcimeni opened 2 years ago

lcimeni commented 2 years ago

Finding Description

This application was found to use deprecated nscoding functionalities for serialization/deserialization of data. Caution should be taken when an application has logic to receive arbitrary data and to then deserialize the data into an object. Remote code execution is possible if raw data is permitted to choose an arbitrary class as the object it becomes deserialized to. In iOS applications, object deserialization/serialization is usually implemented using the NSCoding protocol, which allows the developer to implement the serialization logic for their own classes, or the NSSecureCoding protocol which extends the NSCoding protocol. An implementation which uses the NSCoding protocol is vulnerable to data being deserialized to a different object than what was expected by the developer, also referred to as an “object substitution attack” in Apple's documentation. For more information, watch https://developer.apple.com/videos/play/wwdc2018/222/.

Steps to Reproduce

Source code should be inspected for uses of deprecated serialization functions. These inspections may reveal the use of deprecated serialization functions in use in third party code. NowSecure's automated testing for this vulnerability checks for unsafe use of NSCoding and NSSecureCoding object deserialization. Regardless of the use of NSCoding or NSSecureCoding, the use of the deprecated classes unarchive*ObjectWithData and unarchive*ObjectWithFile are identified.

Business Impact

Applications that do not properly manage the serialization and deserialization of data may be impacted by availability issues if that data is corrupted. In addition, NSCoding is deprecated and as a result, may affect an app's ability to be published.

Remediation Resources

Recommended Fix

Make sure you have adopted NSSecureCoding in the data you decode. When writing a class that supports secure coding, ensure that the + (BOOL)supportsSecureCoding class property getter returns true. Ensure that all - (id)decodeObjectForKey:(NSString*)key calls are replaced with - (id)decodeObjectOfClass:(Class)c forKey:(NSString*)key. Also avoid using the deprecated unarchive*ObjectWithData and unarchive*ObjectWithFile classes and instead implement unarchive*OfClass classes. Refer to NSSecureCoding for further details. It should be noted that third party libraries may be the cause of this finding. In cases where a third party library is the source of this issue, make sure that versions of the library are up-to-date and that the library is necessary.

Code Samples

Good Code Example (.swift)

class Post: NSSecureCoding
{
static var supportsSecureCoding: Bool {
get { return true }
}

// Later on down the road, you might do something like this...
func updatePostsCache()
{
let saveURL = URL(fileURLWithPath: "someDestination")
let archiver = NSKeyedArchiver.archivedData(withRootObject: posts)
try? archiver.write(to: saveURL)
}

// And eventually get it back out...
let postCache:[Data] = /* Data loaded up */
let posts = try postCache.map { postData in
guard let postBlob = try NSKeyedUnarchiver.unarchiveTopLevelObject(with: postData), let post = postBlob as? Post else { throw /* Error handling */ }
return post
}

//Interacting with Object Class
decoder.decodeObject(of:Post.self, forKey: "Posts")

Good Code Example (.objc)

// Inside @interface
@interface Post : NSObject <NSSecureCoding> {

// Add support for secure coding
(BOOL) supportsSecureCoding {
return YES;
}
//...other data
}

//Interacting with Object Class
id obj = [decoder decodeObjectOfClass:Post.class forKey:@"Posts"];
if (![obj isKindOfClass:[MyClass class]]) { /* ...fail... */ }

Additional Guidance

Risk and Regulatory Information

Severity: medium CVSS: 4.3

Application

See more detail in the NowSecure Report