Когда использовать NSSecureCoding

я узнаю о NSSecureCoding протокол, введенный Apple в iOS 6.

из моего понимания до сих пор он должен использоваться всякий раз, когда класс кодирует/декодирует экземпляры самого себя, чтобы предотвратить атаки подстановки.

мне интересно, насколько целесообразно использовать его в других случаях.

в частности, если класс соответствует NSCoding путем кодирования / декодирования переменных экземпляра, в отличие от всего экземпляра сам по себе, все равно было бы целесообразно реализовать NSSecureCoding?


редактировать

Предположим у меня есть класс, который реализует NSCoding как следует

- (void)encodeWithCoder:(NSCoder *)encoder {
    [encoder encodeObject:self.aString forKey:@"aMeaningfulString"];
}

- (id)initWithCoder:(NSCoder *)decoder {
    if((self = [super init])) {
        self.aString = [decoder decodeObjectForKey:@"aMeaningfulString"];
    }
    return self;
}

и предположим также, что XPC не участвует. Экземпляры этого класса будут архивироваться в файлы, хранящиеся на диске.

безопасность-мудрый, есть ли выгода в использовании -decodeObjectOfClass:forKey: в отличие от -decodeObjectForKey:?

3 ответов


в частности, если класс соответствует NSCoding путем кодирования / декодирования его переменных экземпляра, в отличие от всего экземпляра самого себя, было бы целесообразно реализовать NSSecureCoding?

Это зависит от потребностей вашего приложения. Для любого старого приложения сохранение вещей на диск с простым NSCoding прекрасно, потому что записываемая информация и само приложение (не должны) быть чувствительными по своей природе. Но, допустим, вы были банком. выпуск приложения. Вы можете сохранить некоторую информацию об учетной записи или ключ API на диске, чтобы связаться со своей службой, проверить личность пользователя и т. д. Вы можете не хотеть весь объект, но это не должно иметь значения. NSCoder не волнует что читается, только то, что он может читать его и делать свою работу правильно. Это проблема.

безопасность-мудрый, есть ли какие-либо преимущества в использовании-decodeObjectOfClass: forKey: в отличие от - decodeObjectForKey:?

Да, очень. Сам факт, что вы полагаетесь на NSCoder для сериализации/десериализации объекта (не говоря уже о правильном объекте), является огромным вектором атаки. После того, как хакер изменил информацию в формате, используемом NSCoder (plist-подобная структура, которая является одновременно читаемой человеком и очень вредоносной), то нет никакого способа гарантировать, что то, что вы получаете обратно, это то, что вы положили. NSCoder не волнует, что кто-то решил переключить классов содержится в архиве, поэтому вы повторно создаете объект вредоносного класса, а также среда выполнения. На самом деле, достаточно умный хакер будет вводить патч в приложение, чтобы убедиться, что десериализованный объект вызовет какое-то неопределенное состояние (переполнение стека), которое может быть использовано для потенциального использования всего приложения.

decodeObjectOfClass:forKey: позволяет заставить NSCoder быть намного умнее в десериализации, и он исправляет то, что было бы очень большим отверстие. Это не значит, что вы должны никогда используйте NSCoder без NSSecureCoding, но скорее вы должны быть умны в том, в каких ситуациях вы его используете.


когда вы называете decodeObjectForKey: чтобы декодировать переменную экземпляра, объект все еще создается, прежде чем вы сможете проверить его тип класса (причина, почему NSSecureCoding вводится).

поэтому я предполагаю, что те же правила все еще применяются здесь, и поэтому лучше использовать decodeObjectOfClass:forKey вместо decodeObjectForKey: когда вы декодируете переменные экземпляра тоже.


вот мое чувство от чтения документов и NSHipsters пост.

вы используете NSCoding для Тьюринга ваших calsses в двоичный. Это либо для выгрузки данных на диск, либо для межпроцессной связи. Архивация на диск относительно безопасна, однако межпроцессное взаимодействие рискованно, поскольку вы можете не доверять исходному процессу, который предоставляет вам данные.

Итак, во-первых, если вы просто используя NSCoding для размещения объектов настойчиво на диск, тогда вам не нужно беспокоиться о NSSecureCoding (однако его довольно легко реализовать, см. ниже)

в частности, если класс соответствует NSCoding путем кодирования / декодирования его переменных экземпляра, в отличие от всего экземпляра самого себя, было бы целесообразно реализовать NSSecureCoding?

Я не уверен, как вы можете расшифровать весь экземпляр класса. Класс декодируется путем декодирования некоторых данных из архиватора и выполнения что-то с ним.

- (id) initWithCoder:(NSCoder *)aDecoder 
{
   if (self = [super initWithCoder:aDecoder]) 
   {
       // Old way
       //obj myUnsecureObj = [aDecoder decodeObjectForKey:@"myKey"];

       // New way
       obj mySecureObj = [aDecoder decodeObjectOfClass:[MyClass class]
                                                forKey:@"myKey2"];

       // Use mySecureObj (e.g. save to an property / ivar)
   }
   return self;
}

+ (BOOL)supportsSecureCoding {
   return YES;
}