plists possono essere letti in modo sicuro da fonte non attendibile?
Domanda
ho bisogno di semplice comunicazione client-server con applicazione per iPhone, e elenchi di proprietà XML sembra come soluzione abbastanza facile e semplice che mi fa risparmiare fatica di trattare con i delegati del parser XML e la costruzione di queste strutture me stesso.
Mi chiedo solo è saggio utilizzare la classe NSPropertyListSerialization con dati esterni? Ci sono delle caratteristiche plist oscure che potrebbero essere sfruttati?
Soluzione
Sì, è sicuro da usare NSPropertyListSerialization con i dati non attendibili, ma dopo aver acceso la borsa di byte in un hiearchy di tipi plist, è necessario convalidare quei tipi di fa in modo che corrispondano al formato dei dati previsto.
Ad esempio, se vi aspettate un dizionario con chiavi stringa, e NSNumbers come valori, si deve verificare che con qualcosa di simile:
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;
Se non lo fai, la fonte dei dati potrebbe hanno posto i valori plist in archivio con mis abbinati tipi, o valori illegali che potrebbero causare il vostro cliente a comportarsi male e vento per essere una vulnerabilità di sicurezza.
Altri suggerimenti
@ Jon Hess: grazie. Ho creato categoria NSDictionary
per ridurre il numero richiesto di 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