我使用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字符。
任何解决问题的线索都将受到赞赏。谢谢!
答案 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是光荣的半生。
我不相信这段代码来保护我的网络应用程序;在高调的安全库中看到这种事情是令人失望的。