可以从不受信任的来源安全地读取plist吗?

时间:2009-05-29 16:38:11

标签: cocoa security plist

我需要与iPhone应用程序进行简单的客户端 - 服务器通信,并且XML属性列表看起来非常简单和简单,这使我免于处理XML解析器代理和自己构建这些结构的麻烦。

我只是想知道将NSPropertyListSerialization类与外部数据一起使用是否明智?是否有任何模糊的plist功能可以被利用?

2 个答案:

答案 0 :(得分:1)

是的,将NSPropertyListSerialization与不受信任的数据一起使用是安全的,但是在将字节数转换为plist类型的层次结构后,您必须验证这些类型以确保它们符合您预期的数据格式。

例如,如果您希望字典中包含字符串键,而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值放入存档中,匹配类型不匹配,或者非法值可能导致客户端行为不端并最终成为安全漏洞。

答案 1 :(得分:0)

@Jon Hess:谢谢。我创建了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