springBoot集成jsoup解决安全漏洞之XSS注入攻击问题

 更新时间:2025年06月24日 09:55:07   作者: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;
    }
}

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Spring配置shiro时自定义Realm中属性无法使用注解注入的解决办法

    Spring配置shiro时自定义Realm中属性无法使用注解注入的解决办法

    今天小编就为大家分享一篇关于Spring配置shiro时自定义Realm中属性无法使用注解注入的解决办法,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-03-03
  • Java实现Excel转PDF的两种方法详解

    Java实现Excel转PDF的两种方法详解

    使用具将Excel转为PDF的方法有很多,在这里我给大家介绍两种常用的方法:使用spire转化PDF、使用jacob实现Excel转PDF,分别应对两种不一样的使用场景,需要的可以参考一下
    2022-01-01
  • 实例分析Try {} Catch{} 作用

    实例分析Try {} Catch{} 作用

    本文是通过一个简单的实例,向大家介绍了Try {} Catch{}的意义和作用,非常的实用,有需要的小伙伴可以参考下。
    2015-10-10
  • 详解如何配置springboot跳转html页面

    详解如何配置springboot跳转html页面

    这篇文章主要介绍了详解如何配置springboot跳转html页面,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09
  • Java Web监听器如何实现定时发送邮件

    Java Web监听器如何实现定时发送邮件

    这篇文章主要介绍了Java Web监听器如何实现定时发送邮件,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-12-12
  • Java中的集合工具类Collections详解

    Java中的集合工具类Collections详解

    这篇文章主要介绍了Java中的集合工具类Collections详解,java.utils.Collections是集合工具类,用来对集合进行操作,不是Collection集合的根接口,这个要区分开来,需要的朋友可以参考下
    2024-01-01
  • 解决spring-data-jpa mysql建表编码问题

    解决spring-data-jpa mysql建表编码问题

    这篇文章主要介绍了解决spring-data-jpa mysql建表编码问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • 一文解析Java如何连接FTP服务器

    一文解析Java如何连接FTP服务器

    Java 提供了强大的工具和库来实现与 FTP 服务器的连接、文件传输、目录操作等功能,本文将详细介绍如何使用 Java 连接 FTP 服务器,需要的可以参考下
    2024-12-12
  • Spring Bean名称不会被代理的命名技巧

    Spring Bean名称不会被代理的命名技巧

    Spring Bean一些使用小细节就是在不断的源码探索中逐步发现的,今天就来和小伙伴们聊一下通过 beanName 的设置,可以让一个 bean 拒绝被代理
    2023-11-11
  • Mybatis-Plus将字段设置为null解决方法

    Mybatis-Plus将字段设置为null解决方法

    MyBatis-Plus是一个MyBatis的增强工具,在MyBatis的基础上只做增 强不做改变,为简化开发、提高效率而生,下面这篇文章主要给大家介绍了关于Mybatis-Plus将字段设置为null的解决方法的相关资料,需要的朋友可以参考下
    2023-04-04

最新评论