XSS过滤器Filter实现

需求:xxs攻击过滤

测试发现代码转换成图片格式后,可以通过上传文件接口存在服务器上,再次打开时候会执行代码

项目背景:前端采用form+ajax提交数据,后端采用SpringMVC框架,@RequestMapping注解的方法接收前端参数。其中还有用到multipart/form-data传输文件。

思路:
一、实现XSSFilter类(包括工具类和multipartResolver的使用)
二、实现XssHttpServletRequestWraper类
三、注册过滤器(配置类XssConfig和web.xml两种方式)

1.创建过滤器类

1.1XssFilter

在XssFilter需要使用ApplicationContext在初始化filter时候注入multipartResolver,

所以filter需ApplicationContextUtils工具类。filter初始化建立在ApplicationContextUtils加载的基础上,所以需要注释

@DependsOn({"applicationContextUtils"})

详情见SpringBoot使用ApplicationContext.getBean启动报空指针处理记录

package xxxx.web.filter.xss;import xxxx.web.utils.ApplicationContextUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.MultipartResolver;import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.*;
import java.io.IOException;@Component
@DependsOn({"applicationContextUtils"})
public class XssFilter implements Filter{//	为了解决multipart/form-data过滤器过滤之后controller接收不到数据的问题@Autowiredprivate MultipartResolver multipartResolver=null;@Overridepublic void init(FilterConfig filterConfig) throws ServletException {//注入beanmultipartResolver=(MultipartResolver) ApplicationContextUtils.getApplicationContext().getBean("multipartResolver",MultipartResolver.class);}@Overridepublic void doFilter(ServletRequest request , ServletResponse response , FilterChain chain)throws IOException, ServletException{String contentType=request.getContentType();if(contentType!=null && contentType.contains("multipart/form-data")){//form-data过滤MultipartHttpServletRequest multipartRequest=multipartResolver.resolveMultipart((HttpServletRequest) request);XssHttpServletRequestWraper xssRequest=new XssHttpServletRequestWraper(multipartRequest);chain.doFilter(xssRequest, response);}else{//普通过滤XssHttpServletRequestWraper xssRequest=new XssHttpServletRequestWraper((HttpServletRequest)request);chain.doFilter(xssRequest, response);}}@Overridepublic void destroy(){}
}

1.2 工具类ApplicationContextUtils

package xxx.web.utils;import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Configuration;import java.util.Locale;//对Spring容器进行各种上下文操作的工具类
@Configuration
public class ApplicationContextUtils implements ApplicationContextAware {private static ApplicationContext context;@Overridepublic void setApplicationContext(ApplicationContext context) throws BeansException {ApplicationContextUtils.context = context;}public static ApplicationContext getApplicationContext(){return context;}//根据Bean名称获取Bean对象public static Object getBean(String beanName){return context.getBean(beanName);}public static Object getMassage(String key){return context.getMessage(key, null, Locale.getDefault());}
}

1.3multipartResolver文件上传配置

我感觉上传文件可以做到零配置,但是此处项目用到的是不限制文件大小,仅供参考
 

spring.servlet.multipart.enabled=true
spring.servlet.multipart.max-file-size=-1
spring.servlet.multipart.max-request-size=-1

 很多文章中此处用了xml方式

	<!-- =========================注册文件上传 --><bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"><!-- 文件上传大小限制 --><property name="maxUploadSize"><value>104857600</value></property><property name="defaultEncoding"><value>UTF-8</value></property></bean>

文件上传使用multipartResolver具体解析如下:

文件上传解析器MultipartResolver

springBoot中整合文件上传的配置

2.XssHttpServletRequestWraper

package xxx.web.filter.xss;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;public class XssHttpServletRequestWraper extends HttpServletRequestWrapper {public XssHttpServletRequestWraper(HttpServletRequest servletRequest){super(servletRequest);}@Overridepublic String getHeader(String name){return super.getHeader(name);}@Overridepublic String getParameter(String name){String value = super.getParameter(name);return xssEncode(value);}//对以FormData形式提交,Content-Type:application/x-www-from-urlencoded参数过滤@Overridepublic String[] getParameterValues(String name){String[] values=super.getParameterValues(name);if(values==null){return null;}int count=values.length;String[] encodeValues=new String[count];for(int i=0;i<count;i++){encodeValues[i]=xssEncode(values[i]);}return encodeValues;}/*过滤策略:把特殊字符转为HTML实体编码,*这样存在数据库里较安全*返回给前端时会被js解析为正常字符,不影响查看*/public static String xssEncode(String str){if(str == null || str.isEmpty()){return str;}str = str.replaceAll(";", "&#59;");str = str.replaceAll("<", "&#60;").replaceAll(">", "&#62;");str = str.replaceAll("\\(", "&#40;").replaceAll("\\)", "&#41;");str = str.replaceAll("'", "&#39;").replaceAll("\"", "&#34;");str = str.replaceAll("\\$", "&#36;");str = str.replaceAll("%", "&#37;");str = str.replaceAll("\\/", "&#47;").replaceAll("\\\\", "&#92;");str = str.replaceAll(":", "&#58;");str = str.replaceAll("\\?", "&#63;").replaceAll("@", "&#64;");str = str.replaceAll("\\^", "&#94;");return str;}
}

3.注册过滤器

3.1配置类XssConfig

        在这个配置类中,我们通过FilterRegistrationBean来注册XssFilter。setOrder方法用于设置过滤器的执行顺序,addUrlPatterns方法用于指定过滤器应该应用于哪些URL模式,setDispatcherTypes方法用于指定过滤器应该拦截的请求类型(如REQUEST、FORWARD、INCLUDE、ERROR等)。

package xxx.web.filter.xss;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import javax.servlet.DispatcherType;
import org.springframework.context.annotation.Configuration;@Configuration
public class XssConfig {@Autowiredprivate XssFilter xssFilter;@Beanpublic FilterRegistrationBean<XssFilter> xssFilterRegistration() {FilterRegistrationBean<XssFilter> registration = new FilterRegistrationBean<>();registration.setFilter(xssFilter);registration.setOrder(Integer.MAX_VALUE); // 设置过滤器顺序registration.addUrlPatterns("/*"); // 设置过滤器的URL模式registration.setDispatcherTypes(DispatcherType.REQUEST); // 指定过滤器应该拦截的类型return registration;}
}

3.2web.xml配置过滤器

<filter><filter-name>XssFilter</filter-name><filter-class>XssFilter在项目存放的位置</filter-class>
</filter>
<filter-mapping><filter-name>XssFilter</filter-name><url-partten>/*</url-partten><dispatcher>REQUEST</dispatcher>
</filter-mapping>

结果:

<script>alert("1");</script>
后台会解析为&#60;script&#62;alert&#40;&#34;1&#34;&#41;&#59;&#60;&#47;script&#62;
并存入数据库,而在前端显示时又会显示为原来的字符,且不会执行js语句。

返回给前端时,如果是html(str)显示,则能显示原来字符。如果是val(str)返回给文本框的话,则并不会把HTML实体字符解析为正常字符。所以需要我们写个解析函数。在此略

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

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

相关文章

Flutter下拉刷新上拉加载的简单实现方式一

方式一&#xff1a;RefreshIndicatorListView实现 import package:flutter/material.dart;class SimpleRefreshDemoPage extends StatefulWidget {const SimpleRefreshDemoPage({super.key});overrideState<StatefulWidget> createState() {return _SimpleRefreshDemoPa…

VectorDBQA 问答系统

我来解释一下VectorDBQA(Vector Database Question Answering)的用途和实现方式。 VectorDBQA 是一个强大的问答系统&#xff0c;它结合了向量数据库和问答功能。以下是它的主要用途和优势&#xff1a; 智能文档检索和问答 自动从大量文档中找到相关信息生成准确的答案支持对长…

静态库、动态库、framework、xcframework、use_frameworks!的作用、关联核心SDK工程和测试(主)工程、设备CPU架构

1.1库的概念 库&#xff1a;程序代码的集合&#xff0c;编译好的二进制文件加上头文件供使用&#xff0c;共享程序代码的一种方式。 1.2库的分类 根据开源情况分为&#xff1a;开源库&#xff08;能看到具体实现&#xff09;、闭源库&#xff08;只公开调用的的接口&#xf…

天地图入门|标注|移动飞行|缩放,商用地图替换

“天地图”是国家测绘地理信息局建设的地理信息综合服务网站。集成了来自国家、省、市&#xff08;县&#xff09;各级测绘地理信息部门&#xff0c;以及相关政府部门、企事业单位 、社会团体、公众的地理信息公共服务资源&#xff0c;如果做的项目是政府部门、企事业单位尽量选…

Webserver(5.3)线程池实现

目录 线程池locker.hthreadpool.h 线程池 相比于动态地创建子线程&#xff0c;选择一个已经存在的子线程的代价显然要小得多。至于主线程选择哪个子线程来为新任务服务&#xff0c;有多种方式&#xff1a; 主线程使用某种算法来主动选择子线程。最简单、最常用的算法是随机算…

【重装系统后重新配置2】pycharm 终端无法激活conda环境

pycharm 终端无法激活 conda 环境&#xff0c;但是 Windows本地终端是可以激活的 原因是pycharm 默认的终端是 Windows PowerShell 解决方法有两个&#xff1a; 一、在设置里&#xff0c;修改为cmd 二、下面直接选择

云轴科技ZStack助力新远科技开启化工行业智能制造新篇章

新远科技基于云轴科技ZStack Cube超融合和ZStack Zaku容器云平台打造了灵活高效的IT基础设施&#xff0c;实现了IaaS和PaaS层的全面覆盖&#xff0c;优化了资源利用率&#xff0c;降低了硬件成本和运维复杂性&#xff0c;同时强化了数据安全和业务连续性。 化工行业的数字化先…

test 是 JavaScript 中正则表达式对象 (RegExp) 的一种方法,用于测试一个字符串是否匹配某个正则表达式

在你的代码中&#xff0c;test 方法用于验证扫描结果是否符合特定的格式要求。具体来说&#xff0c;/^[A-Za-z\d]{16}$/.test(res.result) 这一行代码用于检查扫描结果 res.result 是否是一个由16个字母或数字组成的字符串。 test 方法的作用 正则表达式匹配&#xff1a; ^ 表…

Golang | Leetcode Golang题解之第546题移除盒子

题目&#xff1a; 题解&#xff1a; func removeBoxes(boxes []int) int {dp : [100][100][100]int{}var calculatePoints func(boxes []int, l, r, k int) intcalculatePoints func(boxes []int, l, r, k int) int {if l > r {return 0}if dp[l][r][k] 0 {r1, k1 : r, k…

数字时代企业的基本数据丢失预防策略

在当今的数字时代&#xff0c;数据丢失预防对企业的重要性怎么强调也不为过。了解与数据丢失相关的风险至关重要&#xff0c;因为人为错误和网络攻击等常见原因可能会产生严重后果。 实施有效的数据丢失预防策略&#xff08;例如安全协议、定期数据备份和员工培训&#xff09;…

使用Element UI实现一个拖拽图片上传,并可以Ctrl + V获取图片实现文件上传

要在 Element UI 的拖拽上传组件中实现 Ctrl V 图片上传功能&#xff0c;可以通过监听键盘事件来捕获粘贴操作&#xff0c;并将粘贴的图片数据上传到服务器。 版本V1&#xff0c;实现获取粘贴板中的文件 注意&#xff0c;本案例需要再你已经安装了Element UI并在项目中正确配…

uni-app小程序echarts中tooltip被遮盖

图表中的文案过长&#xff0c;tooltip溢出容器&#xff0c;会被遮盖住 解决方案&#xff1a; 在echarts的tooltip中有confine属性可将tooltip限制在容器内&#xff0c;不超过容器&#xff0c;就不易被遮盖

axios请求中的data和params的区别

一、 http&#xff1a;超文本传输协议&#xff0c;规定浏览器和服务器之间传输数据的格式 域名&#xff1a;标记访问服务器在互联网中的方位 资源路径&#xff1a;标记资源在服务器下的具体位置 url查询参数&#xff1a;浏览器提供给服务器的额外信息&#xff0c;让服务器返…

设计模式-七个基本原则之一-开闭原则 + SpringBoot案例

开闭原则:(SRP) 面向对象七个基本原则之一 对扩展开放&#xff1a;软件实体&#xff08;类、模块、函数等&#xff09;应该能够通过增加新功能来进行扩展。对修改关闭&#xff1a;一旦软件实体被开发完成&#xff0c;就不应该修改它的源代码。 要看实际场景&#xff0c;比如组内…

Scala的List

1.定义List的类型方式为List[ T ],T表示为数据类型。 2.List是一个不可变的集合&#xff0c;想要获取可变的序列就需要ListBuffer&#xff0c;通过-或方式添加或删除元素&#xff0c;还可以调用remove方法移除元素。 def main(args: Array[String]): Unit {//1.建立 可变列表…

[zotero]Ubuntu搭建WebDAV网盘

搭建Ubuntu Apache WebDAV网盘的综合步骤&#xff0c;使用666端口&#xff1a; 安装Apache和WebDAV模块&#xff1a; sudo apt update sudo apt install apache2 sudo a2enmod dav sudo a2enmod dav_fs创建WebDAV目录&#xff1a; sudo mkdir /var/www/webdav sudo chown www-d…

【深度学习】— 多输入多输出通道、多通道输入的卷积、多输出通道、1×1 卷积层、汇聚层、多通道汇聚层

【深度学习】— 多输入多输出通道、多通道输入的卷积、多输出通道、11 卷积层、汇聚层、多通道汇聚层 多输入多输出通道多通道输入的卷积示例&#xff1a;多通道的二维互相关运算 多输出通道实现多通道输出的互相关运算 11 卷积层11 卷积的作用 使用全连接层实现 11 卷积小结 …

如何解读多年连续发布的指数?

解读多年连续发布的指数是投资者和分析师理解市场趋势、预测未来走向的重要手段。以下是一些关键步骤和方法&#xff0c;有助于系统地解读多年连续发布的指数&#xff1a; 一、收集历史数据 来源&#xff1a;从财经网站、证券交易所官方网站或专业的金融数据服务提供商处获取…

Spring——入门

概述 Spring是什么 Spring是一款主流的Java EE轻量级开源框架&#xff0c;其目的适用于简化Java企业级应用开发难度和开发周期。Spring用途不仅限于服务器端的开发&#xff0c;从简单性、可测试性和松耦合的角度而言&#xff0c;任何Java应用都可以从Spring中受益。Spring框架…

计算机毕业设计Python+Neo4j中华古诗词可视化 古诗词智能问答系统 古诗词数据分析 古诗词情感分析 PyTorch Tensorflow LSTM

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…