在本教程中,您将学习如何保护应用程序免受 CSRF 的侵害。
什么是 CSRF?
如果您已经知道什么 CSRF,请随时继续阅读本分点。 但是,如果您不这样做,CSRF 代表跨站点请求伪造,简单地说,就是攻击者使经过身份验证的用户在网站上执行操作。 结果 – 未经授权的用户执行 Web 应用程序信任的操作。
一个典型的例子是,当用户登录时,网站发送分配给 cookie 的令牌信息作为响应的一部分。 现在用户已经登录,攻击者将尝试使用户从 CSRF 攻击开始的地方访问攻击者的网站。 为了使用户访问其网站,攻击者通常通过电子邮件发送电子邮件。 如果用户单击该链接,则网站上有 1 个或什至更多的 API。 与用户访问过的 Cookie 信息一起发送了请求。 现在,攻击者可以对用户的数据/帐户进行未经授权的更改,例如转移资金。
如何预防 CSRF?
有两种方法可以防止 CSRF。
其中之一是通过实现相同的来源策略。 根据此策略,Web 浏览器允许一个网页中包含的脚本访问另一个网页中的数据,但前提是两个网页具有相同的来源。 此方法取决于 HTTP Cookies 。
另一个是通过应用每个会话/每个请求令牌来过滤作为 CSRF 攻击而来的请求。
Spring 实现中如何防止 CSRF
public class TokenFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
CsrfToken csrfToken = (CsrfToken).request.getAttribute(CsrfToken.class.getName());
if (csrfToken != null) {
Cookie cookie = WebUtils.getCoookie(request, "XSRF-TOKEN");
String token = csrf.getToken();
if (cookie == null || !(token.equals(cookie.getValue())) && token != null) {
cookie = new Cookie("XSRF-TOKEN", token);
cookie.setPath("/");
response.addCookie(cookie);
}
}
filterChain.doFilter(request, response);
}
}
细分
我们创建了一个名为TokenFilter
的类来查找特定的 cookie,在这种情况下,它称为XSRF-TOKEN
。
Cookie cookie = WebUtils.getCoookie(request, "XSRF-TOKEN");
如果没有,则创建一个并分配令牌值,然后将 cookie 添加到服务器响应中。
if (cookie == null || !(token.equals(cookie.getValue())) && token != null) {
cookie = new Cookie("XSRF-TOKEN", token);
cookie.setPath("/");
response.addCookie(cookie);
}
因此,我们设法编写了自己的Filter
类来查找特定的 cookie,以防止 CSRF;如果该 cookie 存在,则将其添加到服务器响应中;如果不存在,则使用给定名称创建一个新的 cookie。