XSS过滤器Filter实现

ops/2024/11/14 13:14:55/

需求: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启动报空指针处理记录

java">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

java">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

java">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等)。

java">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.ppmy.cn/ops/133273.html

相关文章

【网络】完美配置 HTTPS:优化 SSL/TLS 证书以增强网站安全和性能

目录 引言一、申请 SSL/TLS 证书1.1 什么是 SSL/TLS 证书&#xff1f;1.2 如何申请 SSL/TLS 证书&#xff1f;1.3 SSL 证书的种类 二、安装 SSL/TLS 证书2.1 Apache 安装 SSL 证书2.2 Nginx 安装 SSL 证书2.3 IIS 安装 SSL 证书2.4 测试 SSL 配置 三、强制使用 HTTPS3.1 设置 H…

Qt 实现文件监控程序

Qt 实现文件监控程序 flyfish 实现了一个文件监控程序&#xff0c;使用 Qt 框架来监控指定目录中的文件变化&#xff0c;可以监控文件的创建、删除、修改等操作&#xff0c;并将这些操作记录到一个日志文件中。 #include <QCoreApplication> #include <QFileSystem…

【Unity/GameFramework】Start Force ——配置和表加载

文章目录 前言寻找流程具体加载配置加载&#xff1a;获取路径&#xff1a;添加到标志数组&#xff1a;进行实际加载&#xff1a; 数据表加载&#xff1a;获取路径&#xff1a;添加到标志数组&#xff1a;进行实际加载&#xff1a; 语言加载&#xff1a;字体加载&#xff1a; 前…

Linux中的挂载

假设我们有一个 U 盘设备&#xff0c;当我们将 U 盘挂载到 /mnt/usb 目录时&#xff0c;系统会把这个 U 盘文件系统中的内容与 /mnt/usb 关联起来&#xff0c;之后我们只需进入 /mnt/usb&#xff0c;就能看到 U 盘中的所有文件。 挂载前&#xff1a;/mnt/usb 目录是空的。挂载…

重生之从零设计 MySQL 架构

我叫萧剑臣&#xff0c;今年 34 岁&#xff0c;2024 年快接近尾声&#xff0c;在一线城市「浅圳」打拼&#xff0c;在一家名叫「网讯」的互联网大厂工作&#xff0c;是一名资深后端架构师。 已经连续加班到 23:00 半年多才下班&#xff0c;现在已是亥时&#xff0c;push 完代码…

关于倍速播放百度网盘视频

免责声明&#xff1a; 下述内容均为自学探索&#xff0c;仅供学习交流&#xff01;&#xff01;&#xff01; 【侵权删】 正文&#xff1a; 倍速播放百度网盘视频&#xff0c;检索到的通常有&#xff1a;1、使用夸克浏览器倍速播放&#xff1b;2、使用ipad 快捷命令。 推荐…

mac环境配置本地nfs服务

前言 在这篇文章中&#xff0c;讲了在Mac端开启NFS服务&#xff0c;并通过NFS协议让其他设备挂载到你的Mac上。 步骤一&#xff1a;增加配置文件 首先&#xff0c;我们需要编辑NFS的配置文件&#xff0c;以便定义哪些目录可以被远程访问。 打开终端&#xff0c;输入以下命令以编…

OpenEuler 下 Docker 安装、配置与测试实例

文章目录 前言1. 环境准备2. 下载 Docker3.配置服务文件4.配置加速器加速下载docker镜像5. 验证 Docker 安装 前言 Docker 安装大致分为包管理器安装、脚本安装、离线手动安装、容器编排工具安装、桌面版安装等&#xff0c;每种安装各有特点&#xff0c;但涉及知识面不少&…