Spring Security记得我的cookie Unicode字符错了

时间:2016-05-20 21:44:15

标签: spring-mvc cookies unicode spring-security remember-me

我使用spring boot,spring mvc和spring security来制作一个简单的网站。在登录页面中,我有一个记住我的复选框。勾选并登录后,会为浏览器创建一个记住我的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,我们应该首先使用URLEncoder类对其进行编码,然后在读回之后对其进行解码。我是Java和Spring的新手,所以不知道如何自定义记住我的cookie以处理Unicode字符。

任何解决问题的线索都将受到赞赏。谢谢!

1 个答案:

答案 0 :(得分:2)

这是Spring Security中的一个错误。它计算MD5 like this

Hex.encode(digest.digest(data.getBytes()));

使用getBytes的0参数版本,它使用默认编码将Unicode字符编码为字节。默认编码有所不同,但在服务器上显然是一个不能包含中文字符的编码。

永远不应该依赖默认编码。它通常不是UTF,因此不能包含所有Unicode字符。此外,由于它没有修复,当您从一台服务器移动到另一台服务器时,它可能会破坏您的令牌。 Spring应该设置一个明确的UTF编码,例如getBytes("UTF-8")

这不是我记忆中唯一让我担心的财产:

  • 它使用的是MD5,这是一种长期超过其素数的散列算法,并且越来越容易受到攻击。它甚至没有使用HMAC-MD5来减轻这种情况(HMAC专门用于此目的)

  • 所有不受支持的字符都会以静默方式压缩到同一个字符?中,这意味着用户你好的哈希值与用户{{1}的哈希值相同}。因此,理论上可以通过在用户名中创建另一个不受支持的字符的用户,然后更改用户名(或问号本身!)中的任何受害用户登录。 Cookie包含受害者用户名和新用户的哈希值。 (实际上,但是(a)散列中'password'字段的存在使问题变得复杂,尽管它也容易受到Unicode字符压缩的影响,并且(b)幸运的是,cookie本身也使用默认编码进行了错误的解码,从而阻止了一个是从一开始就将任意Unicode字符放入检查器中。)

  • 它将字符串抛出而没有任何转义为分隔符,因此当组件有冒号时会发生奇怪。你可能无法直接对其进行大量攻击,但它很笨拙attempt to work around it是光荣的半生。

我不相信这段代码来保护我的网络应用程序;在高调的安全库中看到这种事情是令人失望的。