CSRF令牌比较在Spring Security 6中失败

vkc1a9a2  于 2023-05-29  发布在  Spring
关注(0)|答案(1)|浏览(173)

我正在编写一个具有Svelte前端和Sping Boot 3后端(版本“3.0.6”)的应用程序。
我阅读了关于针对Breach攻击的新保护,并应用了Spring Security的新配置。
在我的前端,在发送任何POST请求之前,我读取XSRF-TOKEN cookie的值,并将该值复制到header X-XSRF-TOKEN
通过调试代码,我可以看到CsrfFilter能够从头部提取令牌值。
不幸的是,方法XorCsrfTokenRequestAttributeHandler::getTokenValue接收两个相同的字符串作为输入,返回null。假设输入完全由客户端发送的内容定义,我想在将XSRF-TOKEN值复制到header X-XSRF-TOKEN中之前,必须对其进行转换。
方法代码为:

// example call: actualToken = token = "b4b40051-9f64-4d8e-9092-cc84cc769ae0"
private static String getTokenValue(String actualToken, String token) {
    byte[] actualBytes;
    try {
        actualBytes = Base64.getUrlDecoder().decode(actualToken);
    }
    catch (Exception ex) {
        return null;
    }

    byte[] tokenBytes = Utf8.encode(token);
    int tokenSize = tokenBytes.length;
    if (actualBytes.length < tokenSize) {
        // 24 < 36 so we arrive here
        return null;
    }

    // extract token and random bytes
    int randomBytesSize = actualBytes.length - tokenSize;
    byte[] xoredCsrf = new byte[tokenSize];
    byte[] randomBytes = new byte[randomBytesSize];

    System.arraycopy(actualBytes, 0, randomBytes, 0, randomBytesSize);
    System.arraycopy(actualBytes, randomBytesSize, xoredCsrf, 0, tokenSize);

    byte[] csrfBytes = xorCsrf(randomBytes, xoredCsrf);
    return Utf8.decode(csrfBytes);
}

当一切正常时,这个方法应该返回与“token”相同的值,调用equalsConstantTime(csrfToken.getToken(), actualToken)返回true,其中actualToken是上面方法的返回值。
那么,在将cookie XSRF-TOKEN的值复制到header X-XSRF-TOKEN之前,我应该如何处理它呢?

atmip9wb

atmip9wb1#

我在这里找到了解决方案:
https://docs.spring.io/spring-security/reference/5.8/migration/servlet/exploits.html#_i_am_using_a_single_page_application_with_httpsessioncsrftokenrepository
基本上,JavaScript客户端根本不需要与cookie交互。相反,服务器可以定义端点

@GetMapping("/csrf")
public CsrfToken csrfToken(CsrfToken csrfToken) {
    return csrfToken;
}

它返回,例如:

{
    "parameterName":"_csrf",
    "token":"pKpetTa2tv6yhmnko7ZvtaiP7CgX8cB5uBbR1G-ZR6NiKTpIkcltgALX0J-fslyGkJtbgpG_wRFxl_VUgCDm513_dMVUGQ15",
    "headerName":"X-XSRF-TOKEN"
}

沿着cookie中相应的原始令牌,浏览器将自动转发。

相关问题