I need simple client-server communication with iPhone app, and XML property lists seem like quite easy and simple solution that saves me trouble of dealing with XML parser delegates and building these structures myself.
我需要与iPhone应用程序进行简单的客户端 - 服务器通信,并且XML属性列表看起来非常简单和简单,这使我免于处理XML解析器委托和自己构建这些结构的麻烦。
I just wonder is it wise to use NSPropertyListSerialization class with external data? Are there any obscure plist features that could be exploited?
我只是想知道将NSPropertyListSerialization类与外部数据一起使用是否明智?是否有任何可以被利用的模糊plist功能?
2 个解决方案
#1
Yes, it's safe to use NSPropertyListSerialization with untrusted data, but after you turn the bag of bytes into a hiearchy of plist types, you have to validate those types to makes sure they match your expected data format.
是的,将NSPropertyListSerialization与不受信任的数据一起使用是安全的,但是在将字节包转换为plist类型的层次结构后,您必须验证这些类型以确保它们符合您预期的数据格式。
For example, if you expect a dictionary with string keys, and NSNumbers as values, you have to validate that with something like:
例如,如果您希望字典中包含字符串键,而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;
If you don't do that, the source of the data could have placed plist values into the archive with mis matched types, or illegal values that could cause your client to misbehave and wind up being a security vulnerability.
如果您不这样做,数据源可能会将plist值放入存档中,匹配类型不匹配,或者非法值可能导致客户端行为不端并最终成为安全漏洞。
#2
@Jon Hess: thanks. I've created NSDictionary
category to cut down on required number of isKindOfClass
es.
@Jon Hess:谢谢。我已经创建了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
#1
Yes, it's safe to use NSPropertyListSerialization with untrusted data, but after you turn the bag of bytes into a hiearchy of plist types, you have to validate those types to makes sure they match your expected data format.
是的,将NSPropertyListSerialization与不受信任的数据一起使用是安全的,但是在将字节包转换为plist类型的层次结构后,您必须验证这些类型以确保它们符合您预期的数据格式。
For example, if you expect a dictionary with string keys, and NSNumbers as values, you have to validate that with something like:
例如,如果您希望字典中包含字符串键,而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;
If you don't do that, the source of the data could have placed plist values into the archive with mis matched types, or illegal values that could cause your client to misbehave and wind up being a security vulnerability.
如果您不这样做,数据源可能会将plist值放入存档中,匹配类型不匹配,或者非法值可能导致客户端行为不端并最终成为安全漏洞。
#2
@Jon Hess: thanks. I've created NSDictionary
category to cut down on required number of isKindOfClass
es.
@Jon Hess:谢谢。我已经创建了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