XSS过滤器Filter实现

news2024/11/13 10:13:36

需求: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接收不到数据的问题
    @Autowired
    private MultipartResolver multipartResolver=null;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        //注入bean
        multipartResolver=(MultipartResolver) ApplicationContextUtils.getApplicationContext().getBean("multipartResolver",MultipartResolver.class);
    }

    @Override
    public 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);
        }
    }

    @Override
    public 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;

    @Override
    public 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);
    }

    @Override
    public String getHeader(String name){
        return super.getHeader(name);
    }

    @Override
    public String getParameter(String name){
        String value = super.getParameter(name);
        return xssEncode(value);
    }

    //对以FormData形式提交,Content-Type:application/x-www-from-urlencoded参数过滤
    @Override
    public 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 {
    @Autowired
    private XssFilter xssFilter;
    @Bean
    public 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.coloradmin.cn/o/2237795.html

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

相关文章

Windows下mysql数据库备份策略

Windows下mysql的增量备份和全量备份&#xff0c;并利用schtasks设置定时任务执行bat脚本。 一、备份要求 序号 备份类型 备份频次 备份时间 1 增量备份 每周一-每周六各一次 18:00:00 2 全量备份 每周日一次 18:00:00 二、备份方法 2.1增量备份 2.1.1准备工作…

架构师备考-概念背诵(软件工程)

软件工程 软件开发生命周期: 软件定义时期:包括可行性研究和详细需求分析过程,任务是确定软件开发工程必须完成的总目标,具体可分成问题定义、可行性研究、需求分析等。软件开发时期:就是软件的设计与实现,可分成概要设计、详细设计、编码、测试等。软件运行和维护:就是…

【Linux】Linux入门实操——vim、目录结构、远程登录、重启注销

一、Linux 概述 1. 应用领域 服务器领域 linux在服务器领域是最强的&#xff0c;因为它免费、开源、稳定。 嵌入式领域 它的内核最小可以达到几百KB, 可根据需求对软件剪裁&#xff0c;近些年在嵌入式领域得到了很大的应用。 主要应用&#xff1a;机顶盒、数字电视、网络…

【Java项目】基于SpringBoot的【生鲜交易系统】

技术简介&#xff1a; 系统软件架构选择B/S模式、java技术和MySQL数据库等&#xff0c;总体功能模块运用自顶向下的分层思想。 系统简介&#xff1a; 考虑到实际生活中在生鲜交易方面的需要以及对该系统认真的分析,将系统权限按管理员&#xff0c;用户这两类涉及用户划分。 (…

AI Weekly『11月4-10日』: Anthropic发布Claude 3.5 Haiku,腾讯开源混元-Large模型!

大家好&#xff0c;我是木易&#xff0c;一个持续关注AI领域的互联网技术产品经理&#xff0c;国内Top2本科&#xff0c;美国Top10 CS研究生&#xff0c;MBA。我坚信AI是普通人变强的“外挂”&#xff0c;专注于分享AI全维度知识&#xff0c;包括但不限于AI科普&#xff0c;AI工…

贪心算法day3(最长递增序列问题)

目录 1.最长递增三元子序列 2.最长连续递增序列 1.最长递增三元子序列 题目链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a;我们只需要设置两个数进行比较就好。设a为nums[0]&#xff0c;b 为一个无穷大的数&#xff0c;只要有比a小的数字就赋值…

vue实现图片无限滚动播放

本人vue新手菜鸡&#xff0c;文章为自己在项目中遇到问题的记录&#xff0c;如有不足还请大佬指正 文章目录 实现效果代码展示总结 因为刚接触vue&#xff0c;本想着看看能不能用一些element的组件实现图片的轮播效果&#xff0c;尝试使用过element-UI里的走马灯Carouse&#x…

[ 内网渗透实战篇-2 ] 父域子域架构的搭建与安装域环境判断域控定位组策略域森林架构配置信任关系

&#x1f36c; 博主介绍 &#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 _PowerShell &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 &#x1f389;点赞➕评论➕收藏 养成习…

Follow软件的使用入门教程

开篇 看到很多兄弟还不知道怎么用这个当下爆火的浏览器&#xff01;在这里简单给需要入门的小伙伴一些建议&#xff1a; 介绍 简单解释一下&#xff0c;RSS 意思是简易信息聚合&#xff0c;用户可以通过 RSS 阅读器或聚合工具自主订阅并浏览各个平台的内容源&#xff0c;不用…

esp32学习:用虫洞ESP32开发板,快速实现无线图传

我们的虫洞ESP32-S3-EYE开发板&#xff0c;能够完美运行esp who AI代码&#xff0c;所以实现无线图传那是非常容易的&#xff0c;我们先看看esp who代码库中examples目录&#xff1a; 里面有比较多的web例程&#xff0c;在这些例程下&#xff0c;稍作修改&#xff0c;就可以快速…

最新三维视觉下的扩散模型综述——Diffusion Models in 3D Vision: A Survey

目录 摘要 一、引言 二、扩散模型简介 A.扩散模型的介绍 B.扩散模型的数学基础 C.扩散模型的变体 D.三维视觉中的生成过程 三、三维视觉基础 A.三维表示 B.三维视觉中的深度学习方法 C.3D视觉中的挑战 四、三维扩散生成任务 A.无条件生成 B.图像到三维 C.文本到…

JavaSE:运算符 (学习笔记)

目录 一&#xff0c;算术运算符 【1】 共同点&#xff1a; 【2】 不同点&#xff1a; 二&#xff0c;关系运算符 三&#xff0c;逻辑运算符 2&#xff0c;&和&&的区别和联系 { |和||的区别和联系 }---两题类似 四&#xff0c;赋值运算符 五&#xff0c;拓展…

strtok函数详解

strtok函数 strtok 函数是一个字符串分割函数&#xff0c;用于将字符串分割成一系列的标记。这个函数通过一组分隔符字符来确定标记的边界&#xff0c;每次调用都会返回字符串中的下一个标记&#xff0c;并且将原始字符串中的分隔符替换为空字符‘\0’&#xff0c;从而实际上是…

题目练习之二叉树那些事儿(续集)

♥♥♥~~~~~~欢迎光临知星小度博客空间~~~~~~♥♥♥ ♥♥♥零星地变得优秀~也能拼凑出星河~♥♥♥ ♥♥♥我们一起努力成为更好的自己~♥♥♥ ♥♥♥如果这一篇博客对你有帮助~别忘了点赞分享哦~♥♥♥ ♥♥♥如果有什么问题可以评论区留言或者私信我哦~♥♥♥ ✨✨✨✨✨✨个人…

【入门篇】确定字符串是否包含唯一字符——多语言版本

题目跳转&#xff1a;确定字符串是否包含唯一字符 题目解析 这个问题要求我们判断一个字符串中的字符是否唯一&#xff08;忽略字母的大小写&#xff09;&#xff0c;并输出相应的结果。如果字符串中所有的字符都是唯一的&#xff0c;输出 YES&#xff1b;否则&#xff0c;输…

ConcurrentModificationException:检测到并发修改完美解决方法

&#x1f6a6; ConcurrentModificationException&#xff1a;检测到并发修改完美解决方法 &#x1f4a1; &#x1f6a6; ConcurrentModificationException&#xff1a;检测到并发修改完美解决方法 &#x1f4a1;摘要1. 什么是ConcurrentModificationException&#xff1f;&…

并查集 How many tables(hdu 1213) How many answers are wrong(hdu 3038)

目录 前言 并查集 并查集的初始化 并查集的合并 并查集合并的优化&#xff0c;路径压缩 How many tables(hdu 1213) 问题描述 输入 输出 问题分析 代码 带权并查集 How many answers are wrong(hdu 3038) 问题描述 输入 输出 问题分析 代码 前言 感觉并查集总共有两个应…

JavaScript day01 笔记

一、引入方式 JavaScript 程序不能独立运行&#xff0c;它需要被嵌入 HTML 中&#xff0c;然后浏览器才能执行 JavaScript 代码。通过 script 标签将 JavaScript 代码引入到 HTML 中 1️⃣内部 通过 script 标签包裹 JavaScript 代码&#xff08;一般就写在</script>的…

Notepad++ 最新官网中文版在线下载 附文本编辑器安装与基础使用教程

Notepad &#xff08;记事本&#xff09;是一个简单的文本编辑器&#xff0c;预装在所有版本的 Microsoft Windows 操作系统中。它的主要功能是创建、编辑和存储纯文本文件&#xff0c;通常以 .txt 格式保存。Notepad 的设计旨在提供一个轻量级的文本处理工具&#xff0c;适合快…

使用C语言进行信号处理:从理论到实践的全面指南

1. 引言 在现代操作系统中&#xff0c;信号是一种进程间通信机制&#xff0c;它允许操作系统或其他进程向一个进程发送消息。信号可以用来通知进程发生了一些重要事件&#xff0c;如用户请求终止进程、硬件异常、定时器超时等。掌握信号处理技术对于开发健壮、高效的系统程序至…