我需要與iPhone應用程序進行簡單的客戶端 - 服務器通信,並且XML屬性列表看起來像是非常簡單和簡單的解決方案,這使我省卻了處理XML解析器委託並自行構建這些結構的麻煩。plist可以安全地從不受信任的來源讀取?
我只是想知道使用NSPropertyListSerialization類與外部數據是明智的嗎?是否有任何可以被利用的晦澀plist功能?
我需要與iPhone應用程序進行簡單的客戶端 - 服務器通信,並且XML屬性列表看起來像是非常簡單和簡單的解決方案,這使我省卻了處理XML解析器委託並自行構建這些結構的麻煩。plist可以安全地從不受信任的來源讀取?
我只是想知道使用NSPropertyListSerialization類與外部數據是明智的嗎?是否有任何可以被利用的晦澀plist功能?
是的,將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值放入存檔中,但存在錯誤匹配類型或非法值,這些值可能會導致您的客戶端行爲異常並最終成爲安全漏洞。
@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