为了在Restful服务中实现CSRF安全性,我遵循了OWASP中的文档
OWASP建议采用以下方法处理CSRF攻击(参考网址:https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29_Prevention_Cheat_Sheet)
我们需要遵循两个步骤: 1.检查标准标头以验证请求是否为同一来源 2. AND检查CSRF令牌
1。检查标准标头以验证请求是否来源相同: 有人建议检查主持人与推荐人。由于在请求中更改引用和主机头并不容易,检查Referer是否包含主机是我们可以做的第一个检查,我已经处理过了。
2。检查CSRF令牌
检查同步令牌是实现它的一种方法。但它适用于有状态的应用程序。由于我们的应用程序是无状态的,OWASP建议传递一个自定义标头并检查它在服务器端的存在,我实现了相同的。
我试着写下面的代码来检查第一点
String host = "/"+request.getHeader("host")+"/";
String referer = request.getHeader("referer");
if(referer!=null && !referer.contains(host)){
LOGGER.info("referer doesnot contain host");
accessDeniedHandler.handle(request, response, new AccessDeniedException(
"Missing or non-matching CSRF-token"));
return;
}
这在我的本地和测试环境中正常工作,其中只有一条腿在那里。但是当我在具有两条腿的舞台环境中测试它时,Referer和主机名称是不同的。
主机名具有类似
的机器名称machin002:8080
但我期待像
这样的域名sample.domain.com
我是否需要为此主机配置域名?
答案 0 :(得分:0)
首先,您的推荐人检查很弱。
假设合法请求的主机标头为www.example.com
。
如果攻击者从他们自己的域evil.example.org
向您发送跨源请求,则可以通过从此URL发送请求来通过您的检查:https://evil.example.org/?www.example.com
。
易受攻击的代码是
referer.contains(host)
Referer将为https://evil.example.org/?www.example.com
,您可以看到其中包含www.example.com
。
引用检查是一种较弱的CSRF保护形式,因为它解析了这样的错误,有时用户会在浏览器中禁用引用来保护隐私。
因此,您应同时检查Origin
和Referer
,但前者有its own problems。如果您不关心保护旧浏览器,那么这是一个很好的CSRF缓解措施。旧的浏览器可能还有其他错误使它们不安全,所以你可能会争辩说使用旧浏览器的用户无论如何都是不安全的。
我们的申请是无国籍的
这就是为什么你首先需要CSRF?
我是否需要为此主机配置域名?
听起来您需要一个配置变量,您可以在referer
和origin
标题中设置您收到的预期主机。