我需要用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类别以减少所需数量的isKindOfClasses

@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
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top