Spring Security记住我的cookie Unicode字符错误


问题内容

我正在使用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字符。

任何解决问题的线索将不胜感激。谢谢!


问题答案:

这是Spring Security中的错误。它像这样计算MD5

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

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

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

这不是让我记住的唯一记住属性:

  • 它使用的是MD5,这是一种哈希算法,已经过了很长时间,而且越来越容易受到攻击。它甚至都没有使用HMAC-MD5来缓解这种情况(HMAC正是为此目的而设计的)

  • 所有不受支持的字符都被默默压缩为同一字符,?这意味着用户的哈希值你好将与用户的哈希值相同☃☃。因此,从理论上讲,可以通过创建另一个用户名中具有不支持字符的用户,然后以其用户名中包含不支持字符的任何受害者用户身份登录(或问号本身!)。 cookie,以在新用户的哈希中包含受害者用户名。(实际上,(a)散列中“密码”字段的存在使事情变得复杂,尽管这也容易受到Unicode字符挤压的影响;(b)幸运的是,cookie本身也使用默认编码被错误地解码,从而防止了首先是将任意Unicode字符放入检查器)。

  • 它把字符串扔在一起而没有任何分隔符,所以当组件中有冒号时会发生怪异。您可能真的不能直接对它进行太多攻击,但是它很笨拙,解决它尝试光荣地失败了

我不会信任此代码来保护我的Web应用程序。在高调的安全性库中看到这种情况令人失望。