springBoot: Integrating jsoup to solve XSS injection attacks of security vulnerabilities

springBoot: Integrating jsoup to solve XSS injection attacks of security vulnerabilities

cross site scripting

  • Risk : Potential theft or manipulation of customer sessions and cookies, which could be used to impersonate a legitimate user, allowing hackers to view or alter user records and perform transactions as that user.
  • Cause : Dangerous character sanitization was not performed correctly on user input
  • Fixed value : see possible solutions for dangerous character injection

1. Dependence

        <dependency>
            <groupId>org.jsoup</groupId>
            <artifactId>jsoup</artifactId>
            <version>1.11.3</version>
        </dependency>

Two, custom filter

XSS filtering processing logic

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;
    }
}

Filters to prevent XSS attacks

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();
    }
}

register filter

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;
    }
}

Guess you like

Origin blog.csdn.net/weixin_43296313/article/details/128216889