防止 NSString 的堆检查

Rom*_*IER 3 security objective-c ios

我正在努力提高我们的代码安全性。我们使用名为 CheckMarx 的静态代码分析工具。该工具在公司是新工具,特别是我们是唯一使用 Objective C 在 iOS 上工作的团队。

我有一个参数类来连接到服务器,它包含服务器地址,端口,一些参数,登录名和密码密码不应该由用户记录,但。每次需要时,它都会作为令牌从另一个强身份验证服务中检索。它不应该保存为持久值(因为它每次都会改变),所以钥匙串看起来不能满足我的需求。对于演示项目,用户将在文本字段中点击它。该演示项目正在接受安全验证。

运行分析时,我遇到了一个 关于密码的“堆检查”漏洞: https://cwe.mitre.org/data/definitions/244.html 。理论上我理解这个问题,我应该清除存储密码的内存空间,但我不知道在目标 C 中如何实现这一点。

密码是一个 NSString,它是不可变的,所以如果我尝试覆盖 NSString,我只会创建一个新字符串并将旧字符串放在堆中的某个位置。(如果我在 dealloc 方法中覆盖它,我会收到另一个警告,说硬编码字符串对于密码来说是一个不好的做法)。将变量重命名为另一个虚拟变量名称,例如 MyDummyPropThatContainsData

1)ARC会清除指针,但我不认为它会清理堆。所以我相信这不是误报。我错了吗 ?

2)我尝试使用分配有 MAX_SIZE_PASSWORD 的 NSMutableString 。我使用 setString 方法来设置变量(在同一位置)。我通过使用恰好为 MAX_SIZE_PASSWORD 的虚拟值调用 setString 方法在 dealloc 方法中删除它。它删除了警告,这是一个好的做法吗?我非常确定这应该是另一个警告,指出硬编码字符串对于密码来说是一种不好的做法,但没有检测到它。我想坏习惯仍然存在......

3)我想过使用 char* 这样我以后就可以 memset 它,但这对我来说听起来很糟糕。我担心这可能是可靠性和维护问题。这可以解决我的问题吗?是否建议使用 ARC 来管理我自己在需要管理密码的地方分配 char * ?

我在 Objective C 中没有发现任何东西可以防止堆检查漏洞。在 Objective C 中是否有一些常见的方法可以防止这种情况发生?您知道从哪里开始一些好点吗?

任何帮助表示赞赏!

ado*_*oho 5

一条评论,也是一份食谱。在支持无交换或加密交换的系统中,将数据置零基本上是没有意义的。发现密码的主要剩余攻击是直接附加到正在运行的应用程序。我使用钥匙串模式来防御这种攻击。

目标是擦除堆上的秘密。

当我将密码保存在钥匙串中时,它们会以 BLOB 形式返回NSData。这是关键。然后,您可以使用 BLOB 的字节初始化 anNSString并禁止字符串拥有它们 ( freeWhenDone: NO)。虽然我不能保证NSString不复制数据,但情况似乎确实如此。(确保您没有指定导致 NSString 必须重新转换数据的编码。UTF-8 通常工作正常。)

当您使用完密码后NSString,将其释放。(使用 ARC,将其设置为零。)

现在清理堆的关键是使用NSData例程枚举其每个字节数组(通常只有一个),然后将字节设置为NULL。如果您愿意,您可以输入随机字节。您现在可以释放NSDataBLOB。

是的,这打破了可变性保存的所有规则。这就是不安全指针操作的目的。他们不安全。但你在某个特定的地方做某事也是有充分理由的。

由于这是一个相当微妙的操作,我犹豫是否要分享实现上述算法的代码。IMO,您需要对自己的安全卫生负责。

如果上述内容不清楚,我很乐意进一步完善答案。