可以从Plist档案不受信任的来源安全地阅读?
题
我需要用iPhone应用程序简单的客户端 - 服务器通信,以及XML属性列表看起来很容易和简单的解决方案,为我节省了与XML解析器代表打交道,建设这些结构自己的麻烦。
我想知道是明智使用NSPropertyListSerialization类与外部数据?是否有可能被利用任何晦涩难懂的plist功能?
解决方案
是的,它是安全的使用NSPropertyListSerialization与不受信任的数据,但是你把字节包成的plist类型的hiearchy后,您必须验证这些类型可以确保他们的预期的数据格式相匹配。
例如,如果期望具有字符串键,和NSNumbers为值的字典,必须验证与类似:
NSString *errorDescription = nil;
NSPropertyListFormat format = 0;
id topObject = [NSPropertyListSerialization propertyListFromData:plistData mutabilityOption:NSPropertyListImmutable format:&format errorDescription:&errorDescription];
NSDictionary *validDictionary = nil;
if ([topObject isKindOfClass:[NSDictionary class]]) {
BOOL allNumbers = YES;
for(id value in [topObject allValues]) {
allNumbers = allNumbers && [value isKindOfClass:[NSNumber class]];
}
if (allNumbers) {
validDictionary = topObject;
}
}
return validDictionary;
如果你不这样做,数据源可能放置的plist值到归档与管理信息系统相匹配的类型,或可能导致客户端无法正常运作而被清盘的一个安全漏洞非法值。
其他提示
@乔恩赫斯:谢谢。我已经创建NSDictionary
类别以减少所需数量的isKindOfClass
es
@interface NSDictionary (TypedDictionary)
-(NSArray *)arrayForKey:(NSString*)key;
-(NSString *)stringForKey:(NSString*)key;
-(NSDictionary *)dictionaryForKey:(NSString*)key;
@end
@implementation NSDictionary (TypedDictionary)
-(NSArray *)arrayForKey:(NSString*)key {
NSArray *obj = [self objectForKey:key];
return [obj isKindOfClass:[NSArray class]] ? obj : nil;
}
-(NSString *)stringForKey:(NSString*)key {
NSString *obj = [self objectForKey:key];
return [obj isKindOfClass:[NSString class]] ? obj : nil;
}
-(NSDictionary *)dictionaryForKey:(NSString*)key {
NSDictionary *obj = [self objectForKey:key];
return [obj isKindOfClass:[NSDictionary class]] ? obj : nil;
}
@end
不隶属于 StackOverflow