通过RefererInterceptor处理csrf攻击

通过RefererInterceptor处理csrf攻击

一般网站是通过cookie存储客户凭证。当访问一个恶意网站,该网站在页面上构造了一个恶意的http请求,请求一个敏感的数据接口。而该请求会携带上你的cookie。对于服务器而言这是一次合法的请求。这就是csrf攻击。

防止csrf现在最多的方法就是,在渲染html页面的时候添加 csrt_token,提交表单数据的时候,把该token一起提交,在处理请求的时候校验该token的合法性。但是比较麻烦,需要生成。存储,验证等等步骤

比较简单的就是利用浏览器的:Referer
这个httpheader会给服务端暴露,当前请求来自于哪个域名?有了这个信息,就可以判断当前的请求是否是csrf攻击请求。(图片等资源的防盗链也是用的它)

参考

RefererInterceptor

逻辑很简单,只需要把它添加到系统的拦截器链,并且设置需要拦截校验的路径就行

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.MalformedURLException;
import java.net.URL;

public class RefererInterceptor extends HandlerInterceptorAdapter {

    static final Logger LOGGER = LoggerFactory.getLogger(RefererInterceptor.class);

    /**
     * 允许请求的白名单域名
     */
    static final String[] ALLOW_DOMAIN = new String[] {"www.springboot.io", "127.0.0.1"};

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        // 客户端的 referer 头
        String referer = request.getHeader(HttpHeaders.REFERER);
        if (StringUtils.isEmpty(referer)){
            return true;
        }

        // 客户端请求的域名
        String serverName = request.getServerName();

        LOGGER.info("serverName={}, referer={}", serverName, referer);

        try{
            String refererHost = new URL(referer).getHost();

            if (refererHost.equals(serverName)){
                return true;
            }

            // 非同域的请求,判断是否在白名单中
            for (String domain : ALLOW_DOMAIN){
                if (domain.equalsIgnoreCase(refererHost)){
                    // 匹配到白名单域名
                    return true;
                }
            }

        }catch (MalformedURLException malformedURLException){

        }

        /**
         * 非法请求
         */
        response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
        return false;
    }
}

QSCZVS4DDZ8N(}GJ{YI)CXW