我正在学习苹果在iOS 6中引入的NSSecureCoding协议。
到目前为止,我的理解是,为了防止替换攻击,每当类对自身的实例进行编码/解码时,都应该使用它。
我想知道在其他情况下使用它是否合适。
具体地说,如果一个类通过对其实例变量进行编码/解码来符合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。该类的实例将被归档到存储在磁盘上的plist中。
在安全性方面,相对于-decodeObjectForKey:,使用-decodeObjectOfClass:forKey:有什么好处吗?
发布于 2013-06-26 08:58:45
具体地说,如果一个类通过编码/解码它的实例变量来符合NSCoding,而不是它本身的整个实例,那么实现NSSecureCoding仍然是明智的吗?
这取决于您的应用程序的需求。对于任何旧的应用程序来说,使用普通的NSCoding将数据持久化到磁盘上是很好的,因为正在写入的信息和应用程序本身本质上是(不应该)敏感的。但是,假设你是一家发布应用程序的银行。您可以选择将一些帐户信息或API密钥保存到磁盘上,这样您就可以与您的服务通信,验证用户的身份等。您可能不想要整个对象,但这并不重要。NSCoder并不关心正在读取的内容,只关心它能够正确地读取并完成自己的工作。这是一个问题。
安全性--相对于-decodeObjectForKey:,使用-decodeObjectOfClass:forKey:有什么好处吗?
是的,非常喜欢。您依赖NSCoder来序列化/反序列化对象(更不用说正确的对象),这本身就是一个巨大的攻击矢量。一旦黑客修改了NSCoder使用的格式的信息(一种类似plist的结构,它既便于人类阅读,又非常容易被篡改),那么就没有办法保证你得到的是你输入的东西。NSCoder并不关心是否有人决定切换归档中包含的类,以便您重新构造恶意类的对象,运行库也不关心。事实上,足够聪明的黑客会将补丁注入到应用程序中,以确保反序列化的对象会导致某种未定义的状态(堆栈溢出),这可能会被用来利用整个应用程序。
decodeObjectOfClass:forKey:允许您强制NSCoder在反序列化方面变得更聪明,并且它修补了一个非常大的漏洞。这并不是说你永远不应该在没有NSSecureCoding的情况下使用NSCoder,而是说你必须聪明地知道你在什么情况下使用它。
发布于 2013-06-26 00:40:23
当您调用decodeObjectForKey:来解码一个实例变量时,在您可以验证它的类类型之前,该对象仍然是构造的(这就是引入NSSecureCoding的原因)。
因此,我假设这里仍然应用相同的规则,因此在对实例变量进行解码时,最好使用decodeObjectOfClass:forKey而不是decodeObjectForKey:。
发布于 2013-06-26 00:51:02
这是我阅读文档和NSHipsters帖子后的感受。
你可以使用NSCoding将你的调用转换成二进制。这要么用于将数据搜索到磁盘,要么用于进程间通信。存档到磁盘是相对安全的,但是,进程间通信是有风险的,因为您可能不信任为您提供数据的源进程。
因此,首先,如果您只是使用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;
}https://stackoverflow.com/questions/17301769
复制相似问题