5.4.4 当加密失败时

随着安全意识的增加,更多的开发人员使用安全技术来保护应用、系统和用户免遭恶意方的侵害。但是,开发人员仅仅是采用了安全技术,并不意味着他们能够正确地使用。以加密为例,使用加密主要是为了保护被加密数据的机密性。如果加密没有真正的必要性,就不应该使用,因为可能降低性能并且使应用设计复杂化。

作为不恰当的加密提供虚假安全感的例子,考虑一个可通过类似下面的链接访问用户简档页面的应用:

http://hackx/userprofile/userprofile.aspx?uid=ZauX%2f%2fBrHY8%3d

注意以上URL中的uid值。参数uid几乎肯定代表着“用户ID”,包含对应应用中单个用户的唯一值。通常,这些值是顺序的正整数,直接映射到后端数据库中使用的主键值(这不是建议的方式,而是一种常见的容易出错的方式)。在上述URL中,该值不是正整数而是复杂的字符串。尽管不清楚实际上的数值,但是读者应该受到提示,有可能该值是Base64编码,因为末尾有URL编码的%3d(=)。后续对该值的解码生成似乎是随即的8字节字符串,说明该值可能是加密的。

使用本章中讨论过的一些技术攻击这个值可能有好处,也可能一无所获;考虑到8个字节的长度,随机的比特翻转和暴力法是否更简单?攻击这个功能的关键是认识到保护系统中其他对象(如唯一的产品和类别ID)的加密方案也用于uid值。例如,如果你假定加密的uid值的原值是对应于后端数据库表中用户行主关键字的一个整数,那么其他加密的对象ID也是其对应表的主关键字值。这意味着我们可能在对应用的请求中使用加密的产品ID作为一个uid值,并且获得对另一个用户的记录的访问权。为了测试这种攻击是否有效,所需要做的是收集一些加密的产品和类别ID,将它们作为请求用户简档页面userprofile.aspx的uid值。经过这种方法的重复试验,我们发现了宝藏,并且成功地访问了另一个用户包含有趣的个人详细情况的简档。

当然,这个漏洞的根源是控制用户简档页面访问权的授权控制不安全,和使用加密算法的强度无关。最终,访问其他用户的简档必须通过检查请求用户的身份和角色,使用的方法不能仅仅是查询串中简单的uid值。在安全的应用中,当前用户的uid将紧密地与当前已验证的会话关联,通过在应用请求中提供uid值来重载这种关系的企图将会被忽略。