安全漏洞修复-常见问题及解决方案汇总

1.跨站点请求伪造

在项目进行安全测试时,通过AppScan进行漏洞扫描,出现一下问题:

 

 也就是说请求头中缺失"Referer"或未验证Referer的值。由于是前后端分离的项目,前端使用nginx代理,后端部署在tomcat上。因此在后端需要验证Referer的值,添加如下的过滤器:

package com.ljxx.common.filter;

import com.alibaba.fastjson2.JSON;
import com.zxh.model.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
@Configuration
@WebFilter(filterName = "CsrfFilter", urlPatterns = "/*")
public class CsrfFilter implements Filter {
    /**
     * 过滤器配置对象
     */
    FilterConfig filterConfig = null;


    /**
     * 忽略的URL
     */
    @Value("${security.csrf.excludes}")
    private String excludes;


    @Override
    public void init(FilterConfig filterConfig) {
        this.filterConfig = filterConfig;
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
            throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;

        // 已忽略的URL不拦截
        if (isExcludeUrl(request.getServletPath())) {
            filterChain.doFilter(servletRequest, servletResponse);
            return;
        }

        String referer = request.getHeader("Referer");
        String serverName = request.getServerName();
        //本地开发的地址直接放行
        if (serverName.contains("localhost") || serverName.contains("127.0.0.1")) {
            filterChain.doFilter(servletRequest, servletResponse);
        } else {
            // 判断是否存在外链请求本站
            if (null != referer && referer.indexOf(serverName) < 0) {
                log.error("系统不支持当前域名的访问=> serverName:{} => referer:{}", serverName, referer);
                Result error = Result.error("系统不支持当前域名的访问,referer错误!", 502);
                servletResponse.setContentType("application/json; charset=utf-8");
                servletResponse.getWriter().write(JSON.toJSONString(error));
                servletResponse.getWriter().flush();
            } else {
                filterChain.doFilter(servletRequest, servletResponse);
            }
        }
    }

    @Override
    public void destroy() {
        this.filterConfig = null;
    }

    /**
     * 判断是否为忽略的URL
     *
     * @param url
     *            URL路径
     * @return true-忽略,false-过滤
     */
    private boolean isExcludeUrl(String url) {
        if (excludes == null || excludes.isEmpty()) {
            return false;
        }
        List<String> urls = Arrays.asList(excludes.split(","));
        return urls.stream().map(pattern -> Pattern.compile("^" + pattern)).map(p -> p.matcher(url))
                .anyMatch(Matcher::find);
    }
}

这里主要验证Referer的值,如果不是合法的值就直接返回错误信息。

除此之外,在nginx进行转发时,还需要将请求头信息带着,否则这里的服务名一直是127.0.0.1,具体配置详见nginx携带请求头

2."Content-Security-Policy"头缺失

需要配置请求头。具体配置哪种策略需见测试报告的解决建议或参考下面的配置。

3."Content-Security-Policy"头中缺少 "Frame-Anchors"策略或策略不安全

在nginx转发时添加请求头即可

location /api{
     ...
     add_header X-Frame-Options SAMEORIGIN;
     proxy_pass http://127.0.0.1:8001;
}

4."Content-Security-Policy" 头中缺少 "Script-Src" 策略或策略不安全

 在nginx转发时添加请求头即可

location /api{
     ...
     add_header Content-Security-Policy "script-src 'self' 'unsafe-inline' ";
     proxy_pass http://127.0.0.1:8001;
}

5."X-Content-Type-Options"头缺失或不安全

在nginx转发时添加请求头即可(在固定值中已进行了配置说明)

location /api{
     ...
     add_header X-Content-Type-Options nosniff;
     proxy_pass http://127.0.0.1:8001;
}

6."X-XSS-Protection"头缺失或不安全

 在nginx转发时添加请求头即可(在固定值中已进行了配置说明)

location /api{
     ...
     add_header X-XSS-Protection 1;
     proxy_pass http://127.0.0.1:8001;
}

7.检测到隐藏目录

 

 前端使用nginx代理,访问了不存在的路径出现403,解决办法就是将403转为404即可。首先在nginx的html目录新建404.html,内容自定义:

<html>
<head><title>404</title></head>
<meta charset="utf-8">
<body bgcolor="white">
<center><h1>404 - Not Found</h1></center>
</body>
</html>

然后在nginx的server模块中配置将403转到404页面:

server {
     ...
 
    error_page 403 =404 /404.html;
}

那么当访问出现403时就显示的404,在一定程度上保护了服务器的安全。

 

posted @ 2022-12-07 17:01  钟小嘿  阅读(3160)  评论(0编辑  收藏  举报