Spring 安全记住我的 cookie Unicode 字符错误
Spring Security remember me cookie Unicode characters wrong
我正在使用 spring 引导、spring mvc 和 spring 安全来制作一个简单的网站。在登录页面,我有一个记住我的复选框。勾选并登录后,将为浏览器创建一个记住我的 cookie。 chrome 和 firefox 我都试过了。
cookie 在下面。
Name: remember-me
Content: Pz8/Pz8/OjE0NjQ5ODcxMjQxMDk6YTc1MDMzNTM0ZmNhNjc3YmUwOTljZGNjN2EyYTk1NjM
Domain: localhost
Path: /gy
Send For: Any kind of connection
Accessible to Script: No (HttpOnly)
Created: Friday, 20 May 2016 at 21:52:04
Expires: Friday, 3 June 2016 at 21:52:04
以上内容为base64格式。解码后的字符串如下。
??????:1464987124109:a75033534fca677be099cdcc7a2a9563
第一部分是中文用户名,显示为??????。
我知道要将Unicode字符保存到cookie中,我们应该先用URLEncoderclass编码,读回来再解码。我是 Java 和 Spring 的新手,所以不知道如何自定义记住我的 cookie 来处理 Unicode 字符。
任何解决问题的线索都将不胜感激。谢谢!
这是 Spring 安全性中的错误。它计算 MD5 like this:
Hex.encode(digest.digest(data.getBytes()));
使用 getBytes
的 0 参数版本,它使用默认编码将 Unicode 字符编码为字节。默认编码各不相同,但在你的服务器上显然是不能包含汉字的编码。
永远不要依赖默认编码。它通常不是 UTF,因此不能包含所有 Unicode 字符。此外,由于它不是固定的,当您从一台服务器移动到另一台服务器时,它可能会破坏您的令牌。 Spring 应该设置明确的 UTF 编码,例如 getBytes("UTF-8")
.
这不是唯一让我担心的 属性 记住我:
它使用的是 MD5,这是一种早已过时且越来越容易受到攻击的哈希算法。它甚至没有使用 HMAC-MD5 来缓解这种情况(HMAC 正是为此目的而设计的)
所有不受支持的字符都被静默地压缩成相同的字符,?
,这意味着用户 你好
的哈希值将与用户的哈希值相同☃☃
。因此,理论上可以通过创建另一个用户名中具有不同不受支持字符的用户,然后更改其用户名中具有不受支持字符(或问号本身!)的任何受害者用户登录将受害者用户名与新用户的哈希值包含在一起的 cookie。 (然而,在实践中,(a) 散列中 'password' 字段的存在使事情变得复杂,尽管它也容易受到 Unicode 字符压缩的影响,并且 (b) 幸运的是,cookie 本身也使用默认编码被错误解码,从而防止一个来自首先将任意 Unicode 字符输入检查器的方法)。
它把字符串放在一起,没有任何分隔符转义,所以当组件中有冒号时会发生奇怪的事情。你可能不能直接用它做很多攻击,但它很糟糕而且 attempt to work around it光荣地半生半熟。
我不相信这个代码可以保护我的网络应用程序;在高调的安全库中看到这种事情令人失望。
我正在使用 spring 引导、spring mvc 和 spring 安全来制作一个简单的网站。在登录页面,我有一个记住我的复选框。勾选并登录后,将为浏览器创建一个记住我的 cookie。 chrome 和 firefox 我都试过了。
cookie 在下面。
Name: remember-me
Content: Pz8/Pz8/OjE0NjQ5ODcxMjQxMDk6YTc1MDMzNTM0ZmNhNjc3YmUwOTljZGNjN2EyYTk1NjM
Domain: localhost
Path: /gy
Send For: Any kind of connection
Accessible to Script: No (HttpOnly)
Created: Friday, 20 May 2016 at 21:52:04
Expires: Friday, 3 June 2016 at 21:52:04
以上内容为base64格式。解码后的字符串如下。
??????:1464987124109:a75033534fca677be099cdcc7a2a9563
第一部分是中文用户名,显示为??????。
我知道要将Unicode字符保存到cookie中,我们应该先用URLEncoderclass编码,读回来再解码。我是 Java 和 Spring 的新手,所以不知道如何自定义记住我的 cookie 来处理 Unicode 字符。
任何解决问题的线索都将不胜感激。谢谢!
这是 Spring 安全性中的错误。它计算 MD5 like this:
Hex.encode(digest.digest(data.getBytes()));
使用 getBytes
的 0 参数版本,它使用默认编码将 Unicode 字符编码为字节。默认编码各不相同,但在你的服务器上显然是不能包含汉字的编码。
永远不要依赖默认编码。它通常不是 UTF,因此不能包含所有 Unicode 字符。此外,由于它不是固定的,当您从一台服务器移动到另一台服务器时,它可能会破坏您的令牌。 Spring 应该设置明确的 UTF 编码,例如 getBytes("UTF-8")
.
这不是唯一让我担心的 属性 记住我:
它使用的是 MD5,这是一种早已过时且越来越容易受到攻击的哈希算法。它甚至没有使用 HMAC-MD5 来缓解这种情况(HMAC 正是为此目的而设计的)
所有不受支持的字符都被静默地压缩成相同的字符,
?
,这意味着用户你好
的哈希值将与用户的哈希值相同☃☃
。因此,理论上可以通过创建另一个用户名中具有不同不受支持字符的用户,然后更改其用户名中具有不受支持字符(或问号本身!)的任何受害者用户登录将受害者用户名与新用户的哈希值包含在一起的 cookie。 (然而,在实践中,(a) 散列中 'password' 字段的存在使事情变得复杂,尽管它也容易受到 Unicode 字符压缩的影响,并且 (b) 幸运的是,cookie 本身也使用默认编码被错误解码,从而防止一个来自首先将任意 Unicode 字符输入检查器的方法)。它把字符串放在一起,没有任何分隔符转义,所以当组件中有冒号时会发生奇怪的事情。你可能不能直接用它做很多攻击,但它很糟糕而且 attempt to work around it光荣地半生半熟。
我不相信这个代码可以保护我的网络应用程序;在高调的安全库中看到这种事情令人失望。