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

news2024/12/24 21:36:25

先看效果:

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Qt5 编译oracle数据库

库文件 1、Qt源码目录&#xff1a;D:\Qt5\5.15.2\Src\qtbase\src\plugins\sqldrivers\oci 2、oracle客户端SDK: https://www.oracle.com/database/technologies/instant-client/winx64-64-downloads.html 下载各版本中的如下压缩包&#xff0c;一定要版本相同的 将两个压缩包…

jenkins+gitlab配置

汉化 1、安装Localization: Chinese (Simplified)插件 &#xff08;此处我已安装&#xff09; &#xff08;安装完成后重启jenkins服务即可实现汉化&#xff09; 新增用户权限配置 1、安装插件 Role-based Authorization Strategy 2、全局安全配置 3、配置角色权限 4、新建…

运用单例模式思想解决RuntimeException超时问题

今天&#xff0c;排查了一个RuntimeException超时问题&#xff0c;简单记录分享下。 分析关键日志排查如下 查看关键代码 private static Client createClient(String wsdlUrl) {JaxWsDynamicClientFactory jaxWsDynamicClientFactory JaxWsDynamicClientFactory.newInstance…

ElasticView一款ElasticSearch的web可视化工具

ElasticView 是一款用来监控ElasticSearch状态和操作ElasticSearch索引的web可视化工具。它由golang开发而成&#xff0c;具有部署方便&#xff0c;占用内存小等优点 ElasticSearch连接树管理&#xff08;更方便的切换测试/生产环境&#xff09;支持权限管理支持sql转换成dsl语…

Go语言图像处理实战:深入image/color库的应用技巧

Go语言图像处理实战&#xff1a;深入image/color库的应用技巧 引言image/color库基础颜色模型简介颜色类型和接口 image/color库实际应用基本颜色操作创建颜色颜色值转换颜色比较 颜色转换与处理与image库结合使用 性能优化和高级技巧性能考量避免频繁的颜色类型转换使用并发处…

在vue3中实现pptx、word、excel预览

插件推荐 PPTXjs vue-office 代码 <script setup lang"ts" name"home"> import { computed, nextTick, ref, onMounted } from vue; //引入VueOfficeDocx组件 import VueOfficeDocx from vue-office/docx; //引入VueOfficeExcel组件 import VueOf…

探索Web3的奇迹:数字时代的新前景

在数字化时代的潮流中&#xff0c;我们不可避免地迎来了一个全新的篇章——Web3时代的到来。在这个时代中&#xff0c;区块链技术作为数字化世界的核心&#xff0c;正在重塑着我们的生活方式、经济模式以及社会结构。在Web3时代&#xff0c;我们将目睹着一个以去中心化、透明化…

Kubernetes(k8s):深入理解k8s中的亲和性(Affinity)及其在集群调度中的应用

Kubernetes&#xff08;k8s&#xff09;&#xff1a;深入理解k8s中的亲和性&#xff08;Affinity&#xff09;及其在集群调度中的应用 1、什么是亲和性&#xff1f;2、节点亲和性&#xff08;Node Affinity&#xff09;2.1 硬性节点亲和性规则&#xff08;required&#xff09;…

TCP/IP协议—UDP

TCP/IP协议—UDP UDP协议UDP通信特点 UDP头部报文UDP检验 UDP协议 用户数据传输协议 (UDP&#xff0c;User Datagram Protocol) 是一种无连接的协议&#xff0c;提供了简单的数据传输服务&#xff0c;不保证数据的顺序以及完整性。应用层很多通信协议都基于UDP进行传输&#x…

「51媒体网」汽车类媒体有哪些?车展媒体宣传

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 汽车类媒体有很多&#xff0c;具体如下&#xff1a; 汽车之家&#xff1a;提供全面的汽车新闻、评测、导购等内容。 爱卡汽车&#xff1a;同样是一个综合性的汽车信息平台&#xff0c;涵…

iPad 无法解锁?修复 iPad 滑动解锁不起作用的 9 个解决方案

“我的 iPad Pro 一整天都工作正常&#xff0c;直到 20 分钟前。当我解锁它时&#xff0c;它不让我向上滑动。屏幕有响应&#xff0c;但我的 iPad 无法解锁。是否有其他人遇到过这种情况并找到了解决方法&#xff1f;解决方案&#xff1f;” ——来自 Apple 支持社区 iPad 屏幕…

华媒舍:7种方式,打造出旅游媒体套餐

现如今&#xff0c;伴随着旅游业发展与繁荣&#xff0c;更多旅游业发展从业人员越来越重视产品营销品牌基本建设&#xff0c;希望可以将自己的度假旅游产品和服务营销推广给更多的潜在用户。而建立一个优秀的旅游业发展媒体套餐内容品牌是吸引目标客户的重要步骤。下面我们就详…

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

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

2024比特币减半,Web3的“1995时刻”即将到来

随着比特币减半的到来&#xff0c;加密货币市场迎来了一个关键的转折点。2024年的比特币减半不仅是对比特币供应和挖矿激励的一次重大调整&#xff0c;更是对整个Web3应用领域产生深远影响的事件。 首先&#xff0c;比特币减半的事件本身就为市场带来了一种稀缺性的概念&#…

半透明进口特氟龙材质镊子可耐受强酸强碱腐蚀PFA镊子

PFA镊子用于夹取小型片状、薄状、块状样品&#xff0c;广泛应用在半导体、新材料、新能源、原子能、石油化工、无线电、电力机械等行业。 具有耐高低温性&#xff08;可使用温度-200℃&#xff5e;&#xff0b;260℃&#xff09;、耐腐蚀、表面不粘性等特点&#xff0c;用于苛…

代码随想录算法训练营Day53|LC1143 最长公共子序列LC1035 不相交的线LC53 最大子数组和

一句话总结&#xff1a;秒了。 原题链接&#xff1a;1143 最长公共子序列 与昨天的最长重复子数组极度类似。 由于这里是子序列&#xff0c;两者不相等时有dp[i][j] Math.max(dp[i][j - 1], dp[i - 1][j])。同时由于子序列的缘故&#xff0c;dp数组及下标的含义也有了改变&am…

GPDB技术内幕 - SEMI JOIN浅析

GPDB技术内幕 - SEMI JOIN浅析 SEMI JOIN顾名思义&#xff0c;半连接&#xff0c;相对于join字段来说&#xff0c;针对外表的一行记录&#xff0c;内表只要有一条满足&#xff0c;就输出外表记录。注意&#xff0c;这里是仅输出外表记录。GPDB中有几种实现方式&#xff0c;本文…

一篇实操vitrualbox虚拟机根目录扩容(详细,实操陈功)

一篇实操vitrualbox虚拟机根目录扩容&#xff08;详细&#xff0c;实操陈功&#xff09; 创建虚拟介质 第一步、 第二步、 第三步、一直下一步&#xff0c;直到下面的页面 分配空间到更目录下 第一步、 第二步、查看创建的物理磁盘 lsblk第三步、查看原本磁盘可用空间 df …

ARL资产侦察灯塔系统

1、资产侦察灯塔系统搭建 1.1、系统要求 目前暂不支持 Windows&#xff0c;Linux 和 MAC 建议采用 Docker 运行&#xff0c;系统配置最低 2 核 4G。 由于自动资产发现过程中会有大量的的发包&#xff0c;建议采用云服务器可以带来更好的体验 实验环境&#xff1a; 系统&…

新版网络安全等级保护定级指南解读

网络安全等级保护工作的作用对象&#xff0c;主要包括基础信息网络、工业控制系统、云计算平台、物联网、使用移动互联技术的网络和大数据等。 软件开发全套资料获取进主页或者本文末个人名片直接获取。