【SpringBoot XSS存储漏洞 拦截器】Java纯后端对于前台输入值的拦截校验实现 一个类加一个注解结束

先看效果:

1.js注入拦截:
在这里插入图片描述

2.sql注入拦截

在这里插入图片描述

生效只需要两步:

1.创建Filter类,粘贴如下代码:

package cn.你的包命.filter;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.*;
import java.util.regex.Pattern;
import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import com.alibaba.fastjson.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StreamUtils;
import org.springframework.util.StringUtils;

/**
 * LX:XSS对输入值进行过滤,包括数据库关键词、js注入关键词
 */
@WebFilter(filterName = "xssFilter",urlPatterns = "/*",dispatcherTypes = DispatcherType.REQUEST)
public class CrosXssFilter implements Filter {

    private static final Logger logger = LoggerFactory.getLogger(CrosXssFilter.class);
    private static final String xssMsg = "XssERROR 拦截:发现非法的输入值!";

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        if(servletResponse instanceof HttpServletResponse){
            HttpServletResponse httpServletResponse=(HttpServletResponse)servletResponse;
            httpServletResponse.setHeader("Access-Control-Allow-Origin", "*");
            httpServletResponse.setHeader("Access-Control-Allow-Methods", "*");
            httpServletResponse.setHeader("Access-Control-Max-Age", "86400");
            httpServletResponse.setHeader("Access-Control-Allow-Headers", "*");
        }

        XssAndSqlHttpServletRequestWrapper xssRequest=new XssAndSqlHttpServletRequestWrapper(request);
        String method = ((HttpServletRequest) request).getMethod();

        String param = "";

        if ("POST".equalsIgnoreCase(method)) {
            param = this.getBodyString(xssRequest.getReader());
            if(StringUtils.hasText(param)){
                if(xssRequest.checkXSSAndSql(param)){
                    response.setCharacterEncoding("UTF-8");
                    response.setStatus(200);
                    response.setContentType("application/json;charset=UTF-8");
                    PrintWriter out = servletResponse.getWriter();
                    Map res = new LinkedHashMap();
                    res.put("status","0");
                    res.put("msg",xssMsg);
                    out.print(JSON.toJSON(res));
                    out.flush();
                    out.close();
                    return;
                }
            }
        }

        if (xssRequest.checkParameter()) {
            response.setCharacterEncoding("UTF-8");
            response.setStatus(200);
            response.setContentType("application/json;charset=UTF-8");
            PrintWriter out = servletResponse.getWriter();
            Map res = new LinkedHashMap();
            res.put("status","0");
            res.put("msg",xssMsg);
            out.print(JSON.toJSON(res));
            out.flush();
            out.close();
            return;
        }
        filterChain.doFilter(xssRequest, servletResponse);
    }


    // 获取request请求body中参数
    public String getBodyString(BufferedReader br) {
        String inputLine;
        String str = "";
        try {
            while ((inputLine = br.readLine()) != null) {
                str += inputLine;
            }
            br.close();
        } catch (IOException e) {
            logger.error("IOException: " ,e);
        }
        return str;

    }

    @Override
    public void destroy() {
    }

    private class XssAndSqlHttpServletRequestWrapper extends HttpServletRequestWrapper {

        private final Logger logger = LoggerFactory.getLogger(XssAndSqlHttpServletRequestWrapper.class);

        //在这里配置要防的词汇
        private String key = "insert|select|delete|drop|update|truncate";
        private Set<String> notAllowedKeyWords = new HashSet<String>(0);

        HttpServletRequest orgRequest = null;
        private Map<String, String[]> parameterMap;
        private final byte[] body; //用于保存读取body中数据

        public XssAndSqlHttpServletRequestWrapper(HttpServletRequest request) throws IOException{
            super(request);
            orgRequest = request;
            parameterMap = request.getParameterMap();
            body = StreamUtils.copyToByteArray(request.getInputStream());

            String keyStr[] = key.split("\\|");
            for (String str : keyStr) {
                notAllowedKeyWords.add(str);
            }
        }

        @Override
        public Enumeration<String> getParameterNames() {
            Vector<String> vector = new Vector<String>(parameterMap.keySet());
            return vector.elements();
        }

        /**
         * 参数值进行检查
         */
        @Override
        public String getParameter(String name) {
            String[] results = parameterMap.get(name);
            if (results == null || results.length == 0)
                return null;
            else {
                String value = results[0];
                if (value != null) {
                    value = xssEncode(value);
                }
                return value;
            }
        }

        /**
         * 对于数组型的参数值进行检查
         */
        @Override
        public String[] getParameterValues(String name) {
            String[] results = parameterMap.get(name);
            if (results == null || results.length == 0)
                return null;
            else {
                int length = results.length;
                for (int i = 0; i < length; i++) {
                    results[i] = xssEncode(results[i]);
                }
                return results;
            }
        }

        /**
         * 对参数名进行检查
         */
        @Override
        public String getHeader(String name) {

            String value = super.getHeader(xssEncode(name));
            if (value != null) {
                value = xssEncode(value);
            }
            return value;
        }

        /**
         * LX:在这儿,就可以防住有时候客户输入了单双引号,导致页面的js被截断的问题
         *
         * @param s
         * @return
         */
        private String xssEncode(String s) {
            if (s == null || s.isEmpty()) {
                return s;
            } else {
                s = stripXSSAndSql(s);
            }
            StringBuilder sb = new StringBuilder(s.length() + 16);
            for (int i = 0; i < s.length(); i++) {
                char c = s.charAt(i);
                switch (c) {
                    case '\'':
                        sb.append("'");// 转义单引号
                        break;
                    case '\"':
                        sb.append(""");// 转义双引号
                        break;
                    case '&':
                        sb.append("&");// 转义&
                        break;
                    default:
                        sb.append(c);
                        break;
                }
            }


            return sb.toString();
        }

        public HttpServletRequest getOrgRequest() {
            return orgRequest;
        }

        @SuppressWarnings("unused")
        public HttpServletRequest getOrgRequest(HttpServletRequest req) {
            if (req instanceof XssAndSqlHttpServletRequestWrapper) {
                return ((XssAndSqlHttpServletRequestWrapper) req).getOrgRequest();
            }

            return req;
        }

        /**
         *
         * 防止xss跨脚本攻击(替换,根据实际情况调整)
         */

        public String stripXSSAndSql(String value) {
            if (value != null) {
                /** value = value.replaceAll("", ""); ***/
                Pattern scriptPattern = Pattern.compile(
                        "&lt;[\r\n| | ]*script[\r\n| | ]*&gt;(.*?)<!--[\r\n| | ]*script[\r\n| | ]*-->", Pattern.CASE_INSENSITIVE);
                value = scriptPattern.matcher(value).replaceAll("");
                scriptPattern = Pattern.compile("src[\r\n| | ]*=[\r\n| | ]*[\\\"|\\\'](.*?)[\\\"|\\\']",
                        Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
                value = scriptPattern.matcher(value).replaceAll("");
                // Remove any lonesome  tag
                scriptPattern = Pattern.compile("<!--[\r\n| | ]*script[\r\n| | ]*-->", Pattern.CASE_INSENSITIVE);
                value = scriptPattern.matcher(value).replaceAll("");
                // Remove any lonesome <script ...> tag
                scriptPattern = Pattern.compile("<[\r\n| | ]*script(.*?)>",
                        Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
                value = scriptPattern.matcher(value).replaceAll("");
                // Avoid eval(...) expressions
                scriptPattern = Pattern.compile("eval\\((.*?)\\)",
                        Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
                value = scriptPattern.matcher(value).replaceAll("");
                // Avoid e-xpression(...) expressions
                scriptPattern = Pattern.compile("e-xpression\\((.*?)\\)",
                        Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
                value = scriptPattern.matcher(value).replaceAll("");
                // Avoid javascript:... expressions
                scriptPattern = Pattern.compile("javascript[\r\n| | ]*:[\r\n| | ]*", Pattern.CASE_INSENSITIVE);
                value = scriptPattern.matcher(value).replaceAll("");
                // Avoid vbscript:... expressions
                scriptPattern = Pattern.compile("vbscript[\r\n| | ]*:[\r\n| | ]*", Pattern.CASE_INSENSITIVE);
                value = scriptPattern.matcher(value).replaceAll("");
                // Avoid οnlοad= expressions
                scriptPattern = Pattern.compile("onload(.*?)=",
                        Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
                value = scriptPattern.matcher(value).replaceAll("");
            }
            return value;
        }

        public boolean checkXSSAndSql(String value) {
            boolean flag = false;
            if (value != null) {
                // Avoid anything between script tags
                Pattern scriptPattern = Pattern.compile(
                        "<[\r\n| | ]*script[\r\n| | ]*>(.*?)</[\r\n| | ]*script[\r\n| | ]*>", Pattern.CASE_INSENSITIVE);
                flag = scriptPattern.matcher(value).find();
                if (flag) {
                    return flag;
                }
                // Avoid anything in a
                // src="http://www.yihaomen.com/article/java/..." type of
                // e-xpression
                scriptPattern = Pattern.compile("src[\r\n| | ]*=[\r\n| | ]*[\\\"|\\\'](.*?)[\\\"|\\\']",
                        Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
                flag = scriptPattern.matcher(value).find();
                if (flag) {
                    return flag;
                }
                // Remove any lonesome </script> tag
                scriptPattern = Pattern.compile("<!--[\r\n| | ]*script[\r\n| | ]*-->", Pattern.CASE_INSENSITIVE);
                flag = scriptPattern.matcher(value).find();
                if (flag) {
                    return flag;
                }
                // Remove any lonesome <script ...> tag
                scriptPattern = Pattern.compile("<[\r\n| | ]*script(.*?)>",
                        Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
                flag = scriptPattern.matcher(value).find();
                if (flag) {
                    return flag;
                }
                // Avoid eval(...) expressions
                scriptPattern = Pattern.compile("eval\\((.*?)\\)",
                        Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
                flag = scriptPattern.matcher(value).find();
                if (flag) {
                    return flag;
                }
                // Avoid e-xpression(...) expressions
                scriptPattern = Pattern.compile("e-xpression\\((.*?)\\)",
                        Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
                flag = scriptPattern.matcher(value).find();
                if (flag) {
                    return flag;
                }
                // Avoid javascript:... expressions
                scriptPattern = Pattern.compile("javascript[\r\n| | ]*:[\r\n| | ]*", Pattern.CASE_INSENSITIVE);
                flag = scriptPattern.matcher(value).find();
                if (flag) {
                    return flag;
                }
                // Avoid vbscript:... expressions
                scriptPattern = Pattern.compile("vbscript[\r\n| | ]*:[\r\n| | ]*", Pattern.CASE_INSENSITIVE);
                flag = scriptPattern.matcher(value).find();
                if (flag) {
                    return flag;
                }
                // Avoid οnlοad= expressions
                scriptPattern = Pattern.compile("onload(.*?)=",
                        Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
                flag = scriptPattern.matcher(value).find();
                if (flag) {
                    return flag;
                }

                flag=checkSqlKeyWords(value);
            }
            return flag;
        }

        public boolean checkSqlKeyWords(String value){
            String paramValue = value.toLowerCase();//转成小写
            for (String keyword : notAllowedKeyWords) {
                if (paramValue.length() > keyword.length() + 4
                        && (paramValue.contains(" "+keyword)||paramValue.contains(keyword+" ")||paramValue.contains(" "+keyword+" "))) {

                    logger.error(this.getRequestURI()+ "SQL参数中包含敏感词汇(" + keyword
                            + ")");
                    return true;
                }
            }
            return false;
        }

        public final boolean checkParameter() {

            @SuppressWarnings({ "unchecked", "rawtypes" })
            Map<String, String[]> submitParams = new HashMap(parameterMap);

            Set<String> submitNames = submitParams.keySet();
            for (String submitName : submitNames) {
                Object submitValues = submitParams.get(submitName);
                if ((submitValues instanceof String)) {
                    if (checkXSSAndSql((String) submitValues)) {
                        return true;
                    }
                } else if ((submitValues instanceof String[])) {
                    for (String submitValue : (String[])submitValues){
                        if (checkXSSAndSql(submitValue)) {
                            return true;
                        }
                    }
                }
            }
            return false;
        }

        @Override
        public BufferedReader getReader() throws IOException {
            return new BufferedReader(new InputStreamReader(getInputStream()));
        }

        @Override
        public ServletInputStream getInputStream() throws IOException {
            final ByteArrayInputStream bais = new ByteArrayInputStream(body);
            return new ServletInputStream() {

                @Override
                public int read() throws IOException {
                    return bais.read();
                }
            };
        }

    }

}

2.springboot启动类上加上扫描注解:

@ServletComponentScan

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/539101.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++项目——集群聊天服务器项目(十四)客户端业务

大家好~前段时间有些事情需要处理&#xff0c;没来得及更新&#xff0c;实在不好意思。 今天来继续更新集群聊天服务器项目的客户端功能&#xff0c;主要实现客户端业务&#xff0c;包括添加好友、点对点聊天、创建群组、添加群组、群组聊天业务&#xff0c;接下来我们一起来敲…

Unity中支持泰语--没有版权限制

在Unity中支持泰语主要涉及以下几个方面&#xff1a; 选择合适的字体&#xff1a;在Unity中&#xff0c;确保使用支持泰文字符的字体是至关重要的。例如&#xff0c;可以选择使用Noto Serif Thai字体&#xff0c;这是一个支持泰语的字体2。 处理Unity版本问题&#xff1a;某些…

物联网实战--驱动篇之(八)磁编码器(AS5600)

目录 一、AS5600磁编码简介 二、AS5600使用 一、AS5600磁编码简介 AS5600是一款性价比极高的磁编码传感器&#xff0c;一般用于电机转动位置的记录&#xff0c;一般采用IIC通讯&#xff0c;也可以用模拟信号获取转动角度&#xff0c;具体资料在这里。AS5600-ASOM_&#xff08…

ubuntu 20.04 设置国内镜像源(阿里源、清华源)

在网上搜了好多设置国内镜像源&#xff0c;都写的乱七八糟的&#xff0c;都是随便换&#xff0c;最后还是换得一堆问题。 镜像源也是跟版本一一对应的&#xff0c;不能随便一个国内源就还过去用&#xff0c;否则会出现各种各样的问题&#xff0c;我也是吃过亏之后才发现的。 国…

Harmony鸿蒙南向驱动开发-SPI接口使用

功能简介 SPI指串行外设接口&#xff08;Serial Peripheral Interface&#xff09;&#xff0c;是一种高速的&#xff0c;全双工&#xff0c;同步的通信总线。SPI是由Motorola公司开发&#xff0c;用于在主设备和从设备之间进行通信。 SPI接口定义了操作SPI设备的通用方法集合…

MacOS13搭建安卓逆向环境

MacOS中用apktool解包 这里是所有链接&#xff1a;123云盘下载 https://www.123pan.com/s/9QRqVv-JE7Y.html安装apktool https://apktool.org/docs/install/ 或者下载单独的jar包 brew install wgethttps://apktool.org/blog/apktool-2.9.3下载直链&#xff1a;https://co…

【Tomcat 文件读取/文件包含(CVE-2020-1938)漏洞复现】

文章目录 前言 一、漏洞名称 二、漏洞描述 三、受影响端口 四、受影响版本 五、漏洞验证 六、修复建议 前言 近日在做漏扫时发现提示服务器存在CVE-2020-1938漏洞&#xff0c;故文章记录一下相关内容。 一、漏洞名称 Tomcat 文件读取/文件包含漏洞(CVE-2020-1938) 二、漏洞描…

大数据之ClickHouse

大数据之ClickHouse 简介 ClickHouse是一种列式数据库管理系统&#xff0c;专门用于高性能数据分析和数据仓库应用。它是一个开源的数据库系统&#xff0c;最初由俄罗斯搜索引擎公司Yandex开发&#xff0c;用于满足大规模数据分析和报告的需求。 特点 开源的列式存储数据库…

苹果全力升级:用专注AI的M4芯片彻底改造Mac系列

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

FPGA基于VCU的H265视频解压缩,解码后HDMI2.0输出,支持4K60帧,提供工程源码+开发板+技术支持

目录 1、前言免责声明 2、相关方案推荐我这里已有的视频图像编解码方案4K60帧HDMI2.0输入&#xff0c;H265视频压缩方案 3、详细设计方案设计框图FPGA开发板解压视频源Zynq UltraScale VCUVideo Frame Buffer ReadVideo MixerHDMI 1.4/2.0 Transmitter SubsystemVideo PHY Cont…

微服务学习 Eureka注册中心

服务调用时候出现问题&#xff0c;当服务者很多时候&#xff0c;比如不同的端口。消费者如何找到服务者的地址&#xff1f;又如何判断服务者是否健康。 Eureka基本原理&#xff1a; 总结:如果有多个服务提供者&#xff0c;消费者该如何选择&#xff1f; 搭建Eureka注册中心: 1.…

oracle创建整个数据库的只读账户

在源用户readonly 下创建只读用户 reader readonly 的表空间为AA 一、创建只读用户 create user reader identified by 密码 default tablespace AA; 二、授权 grant connect to reader ; 三、获取原账号readonly 的查询权限 select grant select on ||owner||.||object…

Linux的学习之路:7、yum与git

摘要 本章主要是说一下yum和git的操作 目录 摘要 一、什么是yum 二、yum三板斧 1、list 2、install 3、remove 三、怎么创建仓库 四、git三板斧 1、add 2、commit 3、push 4、pull 五、思维导图 一、什么是yum YUM是Yellowdog Updater Modified的简称&#xf…

出海企业如何从海外云手机中受益?

随着全球化的推进&#xff0c;越来越多的企业开始将目光投向海外市场。然而&#xff0c;不同国家和地区的网络环境、政策限制&#xff0c;以及语言文化的差异&#xff0c;给出海企业的市场拓展带来了诸多挑战。在这一背景下&#xff0c;海外云手机作为一种新兴解决方案&#xf…

Jenkins+AWS CodeCommit(git)

问题 需要使用Jenkins搭建一套CI流&#xff0c;即通过git代码托管拉取代码&#xff0c;构建自定分支的代码&#xff0c;构建出jar&#xff0c;并进一步构建出docker镜像&#xff0c;并推送到docker私有库中。 准备 AWS云准备 这里假设已经在CodeCommit已经存在私有git代码仓…

spring boot整合Redis监听数据变化

一、前言 Redis提供了数据变化的通知事件&#xff0c;可以实时监测key和value的变化&#xff0c;客户端可以通过订阅相关的channel来接收这些通知事件&#xff0c;然后做相应的自定义处理&#xff0c;详细的介绍可以参考官方文档Redis keyspace notifications | Docs 使用Red…

Spring Boot | SpringBoot 对 SpringMVC的 “整合支持“

目录: SpringMVC 的 “整合支持” ( 引入"Web依赖启动器"&#xff0c;几乎可以在无任何额外的配置的情况下进行"Web开发")1.SpringMVC "自动配置" 介绍 ( 引入Web依赖启动器"后&#xff0c;SpringBoot会自动进行一些“自动配置”&#xff0…

【Hadoop】下载安装及伪分布式集群搭建教程

目录 1.概述 2.环境准备 3.hadoop安装 3.1.下载安装配置 3.2.伪分布式集群 3.3.注意事项 4.Hadoop集群的组成 1.概述 hadoop有三种安装模式 单机模式&#xff0c;只在一台机器上运行&#xff0c;存储用的本地文件系统而不是HDFS。 伪分布式模式&#xff0c;存储采用HD…

221 基于matlab编制的直齿圆柱齿轮应力计算程序

基于matlab编制的直齿圆柱齿轮应力计算程序&#xff0c;输入设计参数&#xff1a;模数、齿顶高、齿宽、啮合齿数、转速、扭矩、安全系数、压力角、齿轮类型&#xff08;开式、闭式&#xff09;等&#xff0c;输出弯曲应力和许用应力&#xff0c;并对比是否满足要求。并把程序成…

【算法刷题 | 回溯思想 02】4.12(电话号码的字母组合)

文章目录 4.电话号码的字母组合4.1问题4.2解法&#xff1a;回溯4.2.1回溯思路&#xff08;1&#xff09;函数返回值以及参数&#xff08;2&#xff09;终止条件&#xff08;3&#xff09;遍历过程 4.2.2代码实现 4.电话号码的字母组合 4.1问题 给定一个仅包含数字 2-9 的字符…