通过渗透测试发现springboot项目中存在swagger 未授权访问的漏洞,怎样才能方便的修复未授权访问的漏洞,同时又能通过验证正常访问swagger文档呢?本文给出了解决方案,这可能是你看到的最好的解决方案!
大多数人都是直接禁用swagger,这样一来就给开发人员带来了负担,因为需要解决接口文档的问题,相信大家用惯了swagger文档,都不愿意自己再去手动写接口文档了。
swagger未授权访问主要的路径如下,根据版本不同或者自定义的路径,可能会有一定的差异,自定义路径的只需要把自己的路径添加进来即可。
1、/swagger-resources
2、/v2/api-docs
3、/swagger-ui.html
本人提供的解决方案就是通过过滤器的方式对请求进行验证,请求的时候需要在链接后面加上我们自定义的token参数,通过验证token判断是否是合法的访问,注意,添加过滤器后需要在启动类上加上@ServletComponentScan注解才能生效,具体实现如下:
/**
* 解决swagger 未授权访问漏洞,需要在启动类加@ServletComponentScan注解
*
* @author lidongyang
* @date 2023/9/14 16:43
* @since V1.0.0
*/
@Slf4j
@WebFilter(urlPatterns = {"/swagger-resources", "/v2/api-docs","/swagger-ui.html"}, filterName = "swaggerFilter")
public class SwaggerFilter implements Filter {
/**
* 访问swagger的token,默认123@abc,根据自己设置的值替换即可
*/
@Value("${swagger.token:123@abc}")
private String swaggerToken;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
Filter.super.init(filterConfig);
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
log.info("doSwaggerFilter,url:{}", request.getRequestURL());
// 请求来源地址
String referer = request.getHeader("referer");
log.info("referer is {}", referer);
/**
* 1、请求来源地址为空,判断token是否匹配 2、请求来源地址不为空,判断来源地址是否包含正确的token
*/
if (StringUtils.isBlank(referer)) {
// 获取token
String token = request.getParameter("token");
log.info("token is {}", token);
// 来源地址为空,判断token是否匹配
if (!StringUtils.equals(swaggerToken, token)) {
log.error("禁止未授权访问,url:{}", request.getRequestURL());
response.setStatus(403);
servletResponse.setContentType("application/json");
servletResponse.setCharacterEncoding("UTF-8");
servletResponse.getWriter().write("禁止未授权访问");
return;
}
} else if (!referer.contains(swaggerToken)) {
log.warn("禁止未授权访问,url:{}", request.getRequestURL());
response.setStatus(403);
servletResponse.setContentType("application/json");
servletResponse.setCharacterEncoding("UTF-8");
servletResponse.getWriter().write("禁止未授权访问");
return;
}
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
Filter.super.destroy();
}
}
通过添加如上所示的过滤器后,我们就可以通过在路径后面加上token参数进行访问文档地址了,如:127.0.0.1:8000/swagger-ui.html?token=123@abc。
没有加token参数或者token参数匹配不上的请求会直接返回“禁止未授权访问”。这里的token尽量设置复杂一点,token注意保密不要外泄哦!
通过以上方式,解决了swagger未授权访问的问题,还不影响开发人员正常使用swagger文档!