【发布时间】:2015-09-27 05:29:56
【问题描述】:
我正在创建一个链表并使用容器对对象、下一个和上一个属性进行分组。像 Foundation 集合一样,我希望它实现NSSecureCoding。这是声明:
@interface ListContainer : NSObject <NSCopying, NSSecureCoding>
@property (readonly, nonatomic) id object;
@property (nonatomic) ListContainer * next;
@property (nonatomic) ListContainer * previous;
@end
在实现- initWithCoder: 方法时,我不知道该对象使用什么类:
- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
self = [super init];
if (self) {
_object = [aDecoder decodeObjectOfClass:<#(__unsafe_unretained Class)#> forKey:@"object"];
BOOL nextIsNil = [aDecoder decodeBoolForKey:@"nextIsNil"];
if (!nextIsNil) {
// Decode next
_next = [aDecoder decodeObjectOfClass:[ListContainer class] forKey:@"next"];
if (_next == nil) {
return nil;
}
// Link the nodes manually to prevent infinite recursion
self.next.previous = self;
}
}
return self;
}
我应该改用-decodeObjectForKey: 吗?它仍然是安全编码吗?
【问题讨论】:
-
当您对对象进行编码时,您可以使用 NSStringFromClass 使用 id 对象的类名来拥有一个私有变量。当你解码它时,用它来解码它。您甚至可以使用键/值对而不是单独的变量在 NSDictionary 中对其进行编码,解码时只需使用 className 键值来实例化适当的类,并使用适当的值来实例化 value 键值。
-
我确实想到了这一点。但如果我理解正确,当数据来自外部来源(即在线)时,安全编码用于防止实例化未知类型的对象。如果我这样做,我仍然允许攻击者实例化几乎任何对象,因为他们可以在该键中编码他们想要的任何类。他们称之为替代攻击。我希望我的容器受到保护。
-
您将存储包含指定信息的键/值对的 NSDictionary 将使用安全编码机制存储在磁盘上,这意味着必须对对象类型为 NSDictionary 的知识进行解码在揭示键/值数据的知识之前。
-
我不能同意这一点。首先,因为不能保证它会留在磁盘上。编码对象通常用于通过网络发送。其次,因为它是
NSDictionary类型的知识是明确写在编码上的。我认为,这将是一个针对攻击的弱解决方案。打破编码就像我自己编码一个列表并检查二进制结果一样简单 -
忽略之前没有提到通过网络发送此信息的事实以及磁盘上 NSDictionary 将使用安全编码的事实,这意味着没有人能够识别该类是 NSDictionary由于 NSDictionary 是通过以下方式编码的:(其次是因为知道它是 NSDictionary 类型的知识是明确写在编码上的),甚至更进一步,这可能会被自定义容器掩盖。我会注意到还有很多其他方法可以解决这个问题
标签: objective-c nssecurecoding