• 跨站点请求伪造


    1. 跨站点请求伪造

      风险:可能会窃取或操纵客户会话和 cookie,它们可能用于模仿合法用户,从而使黑客能够以该用户身份查看或变更用户记录以及执行事务。
      原因:应用程序使用的认证方法不充分。
      固定值:验证“Referer”头的值,并对每个提交的表单使用 one-time-nonce。

    2. pom.xml添加依赖

    <dependency>
    	<groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-configuration-processor</artifactId>
    	<optional>true</optional>
    </dependency>
    

    3. 配置文件添加配置

    # 信息安全
    security:
      csrf:
        enable: true
        excludes:
    

    4. 添加CSRF过滤器

    import java.io.IOException;
    import java.util.List;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.annotation.WebFilter;
    import javax.servlet.http.HttpServletRequest;
    
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.stereotype.Component;
    
    import lombok.extern.slf4j.Slf4j;
    
    /**
     * CSRF过滤器
     * 
     * @author CL
     *
     */
    @Slf4j
    @Component
    @ConfigurationProperties(prefix = "security.csrf")
    @WebFilter(filterName = "CsrfFilter", urlPatterns = "/*")
    public class CsrfFilter implements Filter {
    
    	/**
    	 * 过滤器配置对象
    	 */
    	FilterConfig filterConfig = null;
    
    	/**
    	 * 是否启用
    	 */
    	private boolean enable;
    
    	public void setEnable(boolean enable) {
    		this.enable = enable;
    	}
    
    	/**
    	 * 忽略的URL
    	 */
    	private List<String> excludes;
    
    	public void setExcludes(List<String> excludes) {
    		this.excludes = excludes;
    	}
    
    	/**
    	 * 初始化
    	 */
    	@Override
    	public void init(FilterConfig filterConfig) throws ServletException {
    		this.filterConfig = filterConfig;
    	}
    
    	/**
    	 * 拦截
    	 */
    	@Override
    	public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
    			throws IOException, ServletException {
    		HttpServletRequest request = (HttpServletRequest) servletRequest;
    
    		// 不启用或者已忽略的URL不拦截
    		if (!enable || isExcludeUrl(request.getServletPath())) {
    			filterChain.doFilter(servletRequest, servletResponse);
    			return;
    		}
    
    		String referer = request.getHeader("Referer");
    		String serverName = request.getServerName();
    
    		// 判断是否存在外链请求本站
    		if (null != referer && referer.indexOf(serverName) < 0) {
    			log.error("CSRF过滤器 => 服务器:{} => 当前域名:{}", serverName, referer);
    			servletResponse.setContentType("text/html; charset=utf-8");
    			servletResponse.getWriter().write("系统不支持当前域名的访问!");
    		} else {
    			filterChain.doFilter(servletRequest, servletResponse);
    		}
    	}
    
    	/**
    	 * 销毁
    	 */
    	@Override
    	public void destroy() {
    		this.filterConfig = null;
    	}
    
    	/**
    	 * 判断是否为忽略的URL
    	 * 
    	 * @param urlPath URL路径
    	 * @return true-忽略,false-过滤
    	 */
    	private boolean isExcludeUrl(String url) {
    		if (excludes == null || excludes.isEmpty()) {
    			return false;
    		}
    		return excludes.stream().map(pattern -> Pattern.compile("^" + pattern)).map(p -> p.matcher(url))
    				.anyMatch(Matcher::find);
    	}
    }
    
  • 相关阅读:
    go语言判断末尾不同的长字符串的方法
    Go语言高级特性总结——Struct、Map与JSON之间的转化
    MacOS使用常用配置
    关于联盟链的一种激励扩张思路(原创)
    密码学中经典算法及应用
    无线网络
    基础的并查集
    找单词
    找零钱
    最大子矩阵
  • 原文地址:https://www.cnblogs.com/cao-lei/p/13704770.html
Copyright © 2020-2023  润新知