首页
点滴
Spring Boot 添加防XSS攻击
> XSS攻击通常指的是通过利用网页开发时留下的漏洞,通过巧妙的方法注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的网页程序 举个简单的例子:假如你的博客网站有留言功能,但却没做有防XSS攻击的处理,那么别人在留言区提交这样一段代码:``,那么在这个页面加载的时候就会弹出1000次“弹死你”的弹窗。我们可以通过过滤JavaScript脚本标签来解决这个问题,这里我用jsoup来做过滤,jsoup是一款Java 的HTML解析器,可直接解析某个URL地址、HTML文本内容。 #### 1、pom.xml引入相关依赖 ```
org.apache.commons
commons-lang3
org.jsoup
jsoup
1.11.3
``` #### 2、application.yml 配置文件加入防xss攻击相关过滤信息 ``` # 防止XSS攻击 xss: # 过滤开关 enabled: true # 排除链接(多个用逗号分隔) excludes: /ui/* # 匹配链接 (多个用逗号分隔) urlPatterns: /api/*,/admin/* ``` #### 3、新建防止XSS攻击的过滤器类 XssFilter 实现 Filter 接口 ``` /** * 防止XSS攻击的过滤器 * * @author Frank * */ public class XssFilter implements Filter { /** * 排除链接 */ public List
excludes = new ArrayList<>(); /** * xss过滤开关 */ public boolean enabled = false; @Override public void init(FilterConfig filterConfig) throws ServletException { String tempExcludes = filterConfig.getInitParameter("excludes"); String tempEnabled = filterConfig.getInitParameter("enabled"); if (StringUtils.isNotEmpty(tempExcludes)) { String[] url = tempExcludes.split(","); for (int i = 0; url != null && i < url.length; i++) { excludes.add(url[i]); } } if (StringUtils.isNotEmpty(tempEnabled)) { enabled = Boolean.valueOf(tempEnabled); } } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse resp = (HttpServletResponse) response; if (handleExcludeURL(req, resp)) { chain.doFilter(request, response); return; } XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper((HttpServletRequest) request); chain.doFilter(xssRequest, response); } private boolean handleExcludeURL(HttpServletRequest request, HttpServletResponse response) { if (!enabled) { return true; } if (excludes == null || excludes.isEmpty()) { return false; } String url = request.getServletPath(); for (String pattern : excludes) { Pattern p = Pattern.compile("^" + pattern); Matcher m = p.matcher(url); if (m.find()) { return true; } } return false; } @Override public void destroy() { } } ``` #### 4、新建XSS过滤处理类 XssHttpServletRequestWrapper 继承 HttpServletRequestWrapper ``` /** * XSS过滤处理 * * @author Frank * */ public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper { public XssHttpServletRequestWrapper(HttpServletRequest request) { super(request); } @Override public String[] getParameterValues(String name) { // 根据实际需求自定义规则。这里content字段为富文本内容不需要过滤 if ("content".equals(name)) { return super.getParameterValues(name); } String[] values = super.getParameterValues(name); if (values != null) { int length = values.length; String[] escapseValues = new String[length]; for (int i = 0; i < length; i++) { // 防xss攻击和过滤前后空格 escapseValues[i] = Jsoup.clean(values[i], Whitelist.relaxed()).trim(); } return escapseValues; } return super.getParameterValues(name); } } ``` #### 5、新建过滤器配置类 FilterConfig,注册过滤器 ``` /** * Filter配置 * @author Frank * */ @Configuration public class FilterConfig { @Value("${xss.enabled}") private String enabled; @Value("${xss.excludes}") private String excludes; @Value("${xss.urlPatterns}") private String urlPatterns; @SuppressWarnings({ "rawtypes", "unchecked" }) @Bean public FilterRegistrationBean xssFilterRegistration() { FilterRegistrationBean registration = new FilterRegistrationBean(); registration.setDispatcherTypes(DispatcherType.REQUEST); registration.setFilter(new XssFilter()); registration.addUrlPatterns(StringUtils.split(urlPatterns, ",")); registration.setName("xssFilter"); registration.setOrder(Integer.MAX_VALUE); Map
initParameters = new HashMap
(); initParameters.put("excludes", excludes); initParameters.put("enabled", enabled); registration.setInitParameters(initParameters); return registration; } } ``` #### 6、新建测试Controller ``` @RestController public class XssTestController { @RequestMapping("/api/xss") public void xssApiTest(String name, String content) { System.out.println("api->name:"+name); System.out.println("api->content:"+content); } /** * bu * @param name * @param content */ @RequestMapping("/ui/xss") public void xssUiTest(String name, String content) { System.out.println("ui->name:"+name); System.out.println("ui->content:"+content); } } ``` #### 7、利用postman测试两个接口,看测试结果 http://localhost:8080/api/xss 请求的两个参数name和content传的值都是`` 这段脚本  看结果可以发现,name字段已经被过滤掉了,而conent字段因为在XssHttpServletRequestWrapper类中做了特殊处理所以没有过滤。  ------------ 再看 http://localhost:8080/ui/xss 这个请求的两个参数name和content传的值也都是`` 这段脚本  看结果可以发现,name和conent字段都没有过滤。因为在application.yml文件中已经配置了 /ui/* 都不过滤 
博客分类
源码解析 (1)
Java (10)
Linux (8)
多线程 (5)
Docker (9)
SpringBoot (14)
微服务 (1)
Redis (15)
MySQL (7)
VMware (3)
Nginx (15)
MyBatis (2)
Git (7)
RabbitMQ (1)
工具类 (12)
前端 (3)
友情链接
layui
© 2020-2025 www.chenhuazhan.com All Rights Reserved 备案号:
桂ICP备17004487号-1
粤公网安备44030002005146