springBoot集成jsoup解决安全漏洞之XSS注入攻击问题
作者:yololee_
这篇文章主要介绍了springBoot集成jsoup解决安全漏洞之XSS注入攻击问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
跨站点脚本编制
- 风险:可能会窃取或操纵客户会话和 cookie,它们可能用于模仿合法用户,从而使黑客能够以该用户身份查看或变更用户记录以及执行事务。
- 原因:未对用户输入正确执行危险字符清理
- 固定值:查看危险字符注入的可能解决方案
一、依赖
<dependency> <groupId>org.jsoup</groupId> <artifactId>jsoup</artifactId> <version>1.11.3</version> </dependency>
二、自定义过滤器
XSS过滤处理逻辑
package com.yolo.springboot.kaptcha.filter; import lombok.extern.slf4j.Slf4j; import org.jsoup.Jsoup; import org.jsoup.safety.Whitelist; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; /** * XSS过滤处理 */ @Slf4j public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper { public XssHttpServletRequestWrapper(HttpServletRequest request) { super(request); } /** * 获取头部参数 * @param v 参数值 */ @Override public String getHeader(String v) { String header = super.getHeader(v); if (header == null || "".equals(header)) { return header; } return Jsoup.clean(super.getHeader(v), Whitelist.relaxed()); } /** * 获取参数 * @param v 参数值 */ @Override public String getParameter(String v) { String param = super.getParameter(v); if (param == null || "".equals(param)) { return param; } return Jsoup.clean(super.getParameter(v), Whitelist.relaxed()); } /** * 获取参数值 * @param v 参数值 */ @Override public String[] getParameterValues(String v) { String[] values = super.getParameterValues(v); if (values == null) { return values; } int length = values.length; String[] resultValues = new String[length]; for (int i = 0; i < length; i++) { // 过滤特殊字符 resultValues[i] = Jsoup.clean(values[i], Whitelist.relaxed()).trim(); if (!(resultValues[i]).equals(values[i])) { log.debug("XSS过滤器 => 过滤前:{} => 过滤后:{}", values[i], resultValues[i]); } } return resultValues; } }
防止XSS攻击的过滤器
package com.yolo.springboot.kaptcha.filter; import org.apache.commons.lang3.StringUtils; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * @ClassName XssFilter * @Description 防止XSS攻击的过滤器 * @Author hl * @Date 2022/12/7 10:07 * @Version 1.0 */ public class XssFilter implements Filter { /** * 排除链接 */ public List<String> noFilterUrls = new ArrayList<>(); /** * xss过滤开关 */ public boolean enabled = true; @Override public void init(FilterConfig filterConfig) throws ServletException { // 从过滤器配置中获取initParams参数 String noFilterUrl = filterConfig.getInitParameter("noFilterUrl"); // 将排除的URL放入成员变量noFilterUrls中 if (StringUtils.isNotBlank(noFilterUrl)) { noFilterUrls = new ArrayList<>(Arrays.asList(noFilterUrl.split(","))); } } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) servletRequest; if (!enabled || handleExcludeURL(req)) { filterChain.doFilter(servletRequest, servletResponse); return; } XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper(req); filterChain.doFilter(xssRequest, servletResponse); } /** * 判断是否为忽略的URL * @return true-忽略,false-过滤 */ private boolean handleExcludeURL(HttpServletRequest request) { if (noFilterUrls == null || noFilterUrls.isEmpty()) { return false; } String url = request.getServletPath(); // return excludes.stream().map(pattern -> Pattern.compile("^" + pattern)).map(p -> p.matcher(url)) // .anyMatch(Matcher::find); for (String pattern : noFilterUrls) { Pattern p = Pattern.compile("^" + pattern); Matcher m = p.matcher(url); if (m.find()) { return true; } } return false; } @Override public void destroy() { Filter.super.destroy(); } }
注册过滤器
package com.yolo.springboot.kaptcha.config; import com.yolo.springboot.kaptcha.filter.XssFilter; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @Configuration public class FilterConfig { @Bean public FilterRegistrationBean<?> xssFilterRegistration() { FilterRegistrationBean<XssFilter> registration = new FilterRegistrationBean<>(); // 将过滤器配置到FilterRegistrationBean对象中 registration.setFilter(new XssFilter()); // 给过滤器取名 registration.setName("xssFilter"); // 设置过滤器优先级,该值越小越优先被执行 registration.setOrder(0); List<String> urlPatterns = new ArrayList<>(); urlPatterns.add("/*"); //这里需要填写排除上传文件的接口 Map<String, String> paramMap = new HashMap<>(); paramMap.put("noFilterUrl", "/login,/logout,/images/*"); // 设置initParams参数 registration.setInitParameters(paramMap); // 设置urlPatterns参数 registration.setUrlPatterns(urlPatterns); return registration; } }
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。