ios - Cuándo usar NSSecureCoding
objective-c security (3)
Estoy aprendiendo sobre el protocolo NSSecureCoding
introducido por Apple en iOS 6.
Desde mi entendimiento hasta ahora, debería usarse siempre que una clase codifique / decodifique instancias de sí misma, para evitar ataques de sustitución.
Me pregunto si sería apropiado usarlo en otros casos.
Específicamente, si una clase se ajusta a NSCoding
codificando / decodificando sus variables de instancia, a diferencia de la instancia completa de sí misma, ¿sería recomendable implementar NSSecureCoding
?
EDITAR
Supongamos que tengo una clase que implementa NSCoding
como sigue
- (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;
}
y supongamos también que no hay XPC involucrado. Las instancias de esta clase se archivarán en una lista almacenada en el disco.
En cuanto a la seguridad, ¿hay algún beneficio en el uso de -decodeObjectOfClass:forKey:
diferencia de -decodeObjectForKey:
:?
Específicamente, si una clase se ajusta a NSCoding codificando / decodificando sus variables de instancia, a diferencia de la instancia completa de sí misma, ¿sería recomendable implementar NSSecureCoding?
Depende de las necesidades de su aplicación. Para cualquier aplicación antigua, persistir en el disco con NSCoding simple está bien, porque la información que se está escribiendo y la aplicación en sí son (no deberían) ser de naturaleza sensible. Pero, digamos que eras un banco lanzando una aplicación. Puede optar por conservar cierta información de la cuenta o una clave API en el disco para poder comunicarse con su servicio, verificar la identidad del usuario, etc. Es posible que no desee el objeto completo, pero eso no debería importar. A NSCoder no le importa lo que se está leyendo, solo que puede leerlo y hacer su trabajo correctamente. Esto es un problema.
En cuanto a la seguridad, ¿hay algún beneficio en el uso de -decodeObjectOfClass: forKey: a diferencia de -decodeObjectForKey :?
Sí mucho así. El mismo hecho de que dependa de NSCoder para serializar / deserializar un objeto (y mucho menos el objeto correcto) es un enorme vector de ataque. Una vez que un pirata informático ha modificado la información en el formato utilizado por NSCoder (una estructura similar a un plist, que es a la vez legible para los humanos y muy maleable), no hay forma de garantizar que lo que recibe es lo que ingresa. A NSCoder no le importa que alguien haya decidido cambiar las clases contenidas en el archivo, por lo que está reconstruyendo un objeto de una clase maliciosa, y tampoco lo hace el tiempo de ejecución. De hecho, un pirata informático lo suficientemente inteligente inyectaría un parche en la aplicación para asegurarse de que el objeto deserializado induciría algún tipo de estado indefinido (un desbordamiento de pila), que podría usarse para explotar potencialmente toda la aplicación.
decodeObjectOfClass:forKey:
permite forzar a NSCoder a ser mucho más inteligente respecto a la deserialización, y parchea lo que sería un agujero muy grande. Eso no quiere decir que nunca debe usar NSCoder sin NSSecureCoding
, sino que debe ser inteligente con respecto a las situaciones en las que lo usa.
Aquí está mi sentimiento al leer la publicación de documentos y NSHipsters .
NSCoding
para NSCoding
tus valores en binarios. Esto es para archivar datos en el disco o para la comunicación entre procesos. Archivar en disco es relativamente seguro, sin embargo, la comunicación entre procesos es arriesgada porque es posible que no confíe en el proceso de origen que le proporciona los datos.
Por lo tanto, primero, si solo está utilizando NSCoding
para escribir objetos de forma persistente en el disco, no tiene que preocuparse por NSSecureCoding
(sin embargo, es bastante fácil de implementar, consulte a continuación)
Específicamente, si una clase se ajusta a NSCoding codificando / decodificando sus variables de instancia, a diferencia de la instancia completa de sí misma, ¿sería recomendable implementar NSSecureCoding?
No estoy seguro de cómo puede decodificar la instancia completa de una clase. Una clase se decodifica decodificando algunos datos del archivador y haciendo algo con ella.
- (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;
}
Cuando llama a decodeObjectForKey:
para decodificar una variable de instancia, el objeto todavía se construye antes de que pueda verificar su tipo de clase (la razón por la que se introduce NSSecureCoding
).
Entonces, asumo que las mismas reglas aún se aplican aquí, y por lo tanto será mejor usar decodeObjectOfClass:forKey
lugar de decodeObjectForKey:
cuando también decodifique variables de instancia.