Spring Security 认证管理漏洞

Posted

技术标签:

【中文标题】Spring Security 认证管理漏洞【英文标题】:Spring security authentication management vulnerability 【发布时间】:2012-05-01 17:30:52 【问题描述】:

Spring 文档说记住我是通过在 cookie 中存储以下信息来实现的 -

base64(用户名 + ":" + expirationTime + ":" + md5Hex(用户名 + ":" + expireTime + ":" 密码 + ":" + key))

我有以下困惑 -

    为什么要使用像 MD5 这样的不安全哈希来消化信息,而不是使用 SHA-1 或 SHA-2。对于这么小的信息,这些对性能的影响会很大吗?

    为什么要通过网络传输这些信息?为什么不在服务器上维护一个加密安全随机数和此信息的映射,只返回映射密钥作为 cookie。 AFAIK 这是 Servlet API 使用的方法,被认为更安全。

【问题讨论】:

【参考方案1】:

Simple Hash-Based 令牌使用的 MD5 哈希不是该方法的漏洞。

使用 MD5 对密码进行哈希处理是危险的,因为给定现有密码的哈希值,您可以找到另一个哈希到相同值的密码(使用彩虹表)。

但是,在这种情况下,MD5 并未用于散列密码,而是用作MAC。如果您确实使用彩虹表来找到与该哈希冲突的值,那么您如何准确地使用该值?

对 cookie 使用不同的散列函数可能会让您感觉更安全,但在这种情况下并不能提供更多安全性。

如果您想要更高的安全性,那么您应该使用持久哈希令牌方法。简单哈希令牌以明文形式公开用户名,容易受到重放攻击。 Persistent Token 避免了这些问题。

无论哪种方式,您都应该通过设置其 Secure 和 Http-only 标志来保护您的 remember-me cookie。

【讨论】:

(+1) 用于清楚地解释持久哈希令牌方法的优点 - 即使这只是 cmets 提出的问题【参考方案2】:

让我们从第二个问题开始,因为它更相关:

第二个问题“为什么要通过网络传输密码……”答案:

因为你描述的只是Simple Hash-Based Token Approach

如果您向下滚动页面 Spring Security Reference: Chapter 10 Remember-Me Authentication,您会看到 Spring Security 还可以使用不同的记住我的方法:Chapter 10.3 Persistent Token Approach。这就是您在第二个问题中的建议。


第一个问题:简短回答“对于这么小的信息,这些对性能的影响会很大吗?” - 没有

所以如果你想使用Simple Hash-Based Token Approach并且觉得MD5是不安全的,那么你可以继承TokenBasedRememberMeService[javadoc]并覆盖String makeTokenSignature(long tokenExpiryTime, String username, String password)方法。例如(未经测试)

protected String makeTokenSignature(long tokenExpiryTime, String username, String password) 
    String data = username + ":" + tokenExpiryTime + ":" + password + ":" + getKey();
    MessageDigest digest;
    try 
        digest = MessageDigest.getInstance("SHA-256");
     catch (NoSuchAlgorithmException e) 
        throw new IllegalStateException("No SHA-256 algorithm available!");
    

    return new String(Hex.encode(digest.digest(data.getBytes())));

【讨论】:

覆盖 makeTokenSignature() 看起来是一个不错的方法,因为我认为 SHA-2 不会被破坏。我想知道在什么情况下需要使用持久令牌方法。 因为持久化方法更加安全。不提供有关密码的信息总是比发送加密密码更好。 ——但这种讨论往往是理论上的。 -- 无论如何,我更喜欢持久性令牌方法,因为这可以实现删除此类令牌等附加功能。 持久令牌方法肯定更好,但我不确定在这种情况下使用 MD5 有什么不安全性,因为它基本上被用作签名。您需要访问散列密码和重现 MD5 散列的密钥。 @ericacm:认为问题不在于复制令牌,问题在于有人可以从令牌中“重新计算”密码。 我不确定这怎么可能。

以上是关于Spring Security 认证管理漏洞的主要内容,如果未能解决你的问题,请参考以下文章

Spring Security sec:授权抛出异常

Spring Security 自定义登录认证

spring boot整合 spring security之会话管理

Spring boot+Spring security+JWT实现前后端分离登录认证及权限控制

如何从 Spring Security 中的会话管理(超时/并发检查)中排除某些页面?

Gateway 整合 Spring Security鉴权