业务服务:xss攻击

文章目录

  • 前言
  • 一、使用注解预防
    • 1. 添加依赖
    • 2. 自定义注解
    • 3. 自定义校验逻辑
    • 4. 使用
  • 二、使用过滤器
    • 1. 添加配置
    • 2. 创建配置类
    • 3. 创建过滤器
    • 4. 创建过滤器类
    • 5. 使用


前言

xss攻击时安全领域中非常常见的一种方法,保证我们的系统安全是非常重要的

xss攻击简单来说就是在用户输入内容中添加脚本< script >…< script >
这里面可能包含获取cookie,


一、使用注解预防

1. 添加依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId>
</dependency>

2. 自定义注解

@Retention(RetentionPolicy.RUNTIME)
@Target(value = {ElementType.METHOD, ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.PARAMETER})
@Constraint(validatedBy = {XssValidator.class})
public @interface Xss {String message() default "不允许任何脚本运行";Class<?>[] groups() default {};Class<? extends Payload>[] payload() default {};}

3. 自定义校验逻辑

public class XssValidator implements ConstraintValidator<Xss, String> {@Overridepublic boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) {// 这里用的hutool的工具类return !ReUtil.contains(HtmlUtil.RE_HTML_MARK, value);}}

4. 使用

创建实体类

@Data
public class Book {private Long id;private String name;@Xssprivate String content;
}

创建book控制器

@Validated
@RestController
@RequestMapping("/book")
public class BookController {@PostMappingpublic void save(@Validated @RequestBody Book book){System.out.println(book);}
}

发送请求

在这里插入图片描述

可以看到系统抛出了异常,这样我们就成功了使用注解完成了脚本验证

在这里插入图片描述

二、使用过滤器

注解的方式需要一个一个的添加,这显然是不太方便的。我们可以通过过滤器的方式对前端传递过来的参数进行统一处理

1. 添加配置

# 防止XSS攻击
xss:# 过滤开关enabled: true# 排除链接(多个用逗号分隔)excludes: # 匹配链接urlPatterns: /book/*

2. 创建配置类

@Data
@Component
@ConfigurationProperties(prefix = "xss")
public class XssProperties {/*** 过滤开关*/private String enabled;/*** 排除链接(多个用逗号分隔)*/private String excludes;/*** 匹配链接*/private String urlPatterns;}

3. 创建过滤器

@Configuration
public class FilterConfig {@Autowiredprivate XssProperties xssProperties;// 关闭校验注解@SuppressWarnings({"rawtypes", "unchecked"})@Bean// xss.enabled==true时,注入bean@ConditionalOnProperty(value = "xss.enabled", havingValue = "true") public FilterRegistrationBean xssFilterRegistration() {// 创建过滤器注册器FilterRegistrationBean registration = new FilterRegistrationBean();// 设置运行类型registration.setDispatcherTypes(DispatcherType.REQUEST);// 设置过滤器registration.setFilter(new XssFilter());// 添加拦截路径registration.addUrlPatterns(StrUtil.split(xssProperties.getUrlPatterns(), StrUtil.C_COMMA).toArray(String[]::new));registration.setName("xssFilter");// 设置优先级为最高registration.setOrder(FilterRegistrationBean.HIGHEST_PRECEDENCE);// 添加自定义参数Map<String, String> initParameters = new HashMap<String, String>();initParameters.put("excludes", xssProperties.getExcludes());registration.setInitParameters(initParameters);return registration;}
}

4. 创建过滤器类

public class XssFilter implements Filter {/*** 排除链接*/public List<String> excludes = new ArrayList<>();/*** 初始化的时候将排除连接根据,分割添加到excludes中* @param filterConfig* @throws ServletException*/@Overridepublic void init(FilterConfig filterConfig) throws ServletException {String tempExcludes = filterConfig.getInitParameter("excludes");if (StrUtil.isNotBlank(tempExcludes)) {String[] url = tempExcludes.split(StrUtil.COMMA);excludes.addAll(Arrays.asList(url));}}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {HttpServletRequest req = (HttpServletRequest) request;HttpServletResponse resp = (HttpServletResponse) response;if (handleExcludeURL(req, resp)) {chain.doFilter(request, response);return;}XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper((HttpServletRequest) request);chain.doFilter(xssRequest, response);}/*** 判断是否为排除过滤路径* @param request* @param response* @return*/private boolean handleExcludeURL(HttpServletRequest request, HttpServletResponse response) {String url = request.getServletPath();String method = request.getMethod();// GET DELETE 不过滤if (method == null || HttpMethod.GET.matches(method) || HttpMethod.DELETE.matches(method)) {return true;}return matches(url, excludes);}public static boolean matches(String str, List<String> strs) {if (StrUtil.isBlank(str) || CollUtil.isEmpty(strs)) {return false;}for (String pattern : strs) {if (isMatch(pattern, str)) {return true;}}return false;}public static boolean isMatch(String pattern, String url) {AntPathMatcher matcher = new AntPathMatcher();return matcher.match(pattern, url);}@Overridepublic void destroy() {}
}
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {/*** @param request*/public XssHttpServletRequestWrapper(HttpServletRequest request) {super(request);}/*** 将url拼接的参数进行脚本过滤* @param name* @return*/@Overridepublic String[] getParameterValues(String name) {String[] values = super.getParameterValues(name);if (values != null) {int length = values.length;String[] escapesValues = new String[length];for (int i = 0; i < length; i++) {// 防xss攻击和过滤前后空格escapesValues[i] = HtmlUtil.cleanHtmlTag(values[i]).trim();}return escapesValues;}return super.getParameterValues(name);}/*** 对body的脚本参数进行过滤* @return* @throws IOException*/@Overridepublic ServletInputStream getInputStream() throws IOException {// 非json类型,直接返回if (!isJsonRequest()) {return super.getInputStream();}// 为空,直接返回String json = StrUtil.str(IoUtil.readBytes(super.getInputStream(), false), StandardCharsets.UTF_8);if (StringUtils.isEmpty(json)) {return super.getInputStream();}// xss过滤json = HtmlUtil.cleanHtmlTag(json).trim();byte[] jsonBytes = json.getBytes(StandardCharsets.UTF_8);final ByteArrayInputStream bis = IoUtil.toStream(jsonBytes);return new ServletInputStream() {@Overridepublic boolean isFinished() {return true;}@Overridepublic boolean isReady() {return true;}@Overridepublic int available() throws IOException {return jsonBytes.length;}@Overridepublic void setReadListener(ReadListener readListener) {}@Overridepublic int read() throws IOException {return bis.read();}};}/*** 是否是Json请求*/public boolean isJsonRequest() {String header = super.getHeader(HttpHeaders.CONTENT_TYPE);return StringUtils.startsWithIgnoreCase(header, MediaType.APPLICATION_JSON_VALUE);}
}

5. 使用

发送请求

在这里插入图片描述

可以看到传递的脚本被成功过滤掉

在这里插入图片描述

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

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

相关文章

P2123皇后游戏

P2123皇后游戏 参考题解 #include <iostream> #include <algorithm> using namespace std;int T; int n; long long res;struct Person {int a,b,d; }p[20005];bool person_cmp(const Person& x,const Person& y) {if(x.d y.d){if(x.d < 0)return x.a …

torchrun在验证集使用一个GPU时报NCCL超时:Watchdog caught collective operation timeout的解决方案

有时候在分布式训练时&#xff0c;可能会出现nccl通信超时的问题&#xff0c;出现的原因好像是在某些数据处理、加载等过程&#xff0c;多个进程一起完成&#xff0c;但是某些计算&#xff08;比如loss具体不知道都有啥&#xff09;需要rank0自己来做&#xff0c;但是由于默认的…

语言模型:解密AI语言理解之道

在这个信息爆炸的时代,我们每天都在与海量的文本数据打交道。如何从这些文本中提炼出有价值的信息,成为了科技界的一大挑战。而语言模型,正是解决这一挑战的关键技术之一。今天,就让我们一起走进语言模型的神秘世界,探索其原理、实战与评估的奥秘。 一、原理篇:语言模型…

Javascript——Symbol简单了解

一、Symbol(符号) 1.1 MDN链接&#xff1a;yield - JavaScript | MDN (mozilla.org) 1.2 Symbol简介 Symbol(符号)是ECMAScript6新增的数据类型。符号是原始值&#xff0c;且符号实例是唯一、不可变的。符号的用途是确保对象属性使用唯一标识符&#xff0c;不会发生属性冲突…

TCP(socket 套接字)编程 1

一、TCP套接字编程架构如下 二、相关代码实现 1、服务器端代码 package com.company;import java.io.IOException; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket;public class Main {public static void main(String[] args) {…

5.88 BCC工具之tcpsynbl.py解读

一,工具简介 tcpsynbl工具以直方图的形式显示SYN到达时的TCP SYN积压大小。这可以让我们了解应用程序距离达到积压限制并丢弃SYN(导致SYN重传产生性能问题)还有多远。 TCP SYN 数据包则通常用于启动 TCP 三次握手过程的第一次握手。 二,代码示例 #!/usr/bin/env python…

javaWeb健身房管理系统

一、简介 随着人们健康意识的增强和生活水平的提高&#xff0c;健身已经成为了现代人生活中不可或缺的一部分。为了更好地管理健身房的日常运营&#xff0c;我们设计并开发了一款基于 JavaWeb 的健身房管理系统。本系统采用了最新的技术&#xff0c;包括 Spring Boot、MyBatis…

nacos集群搭建实战

集群结构图 初始化数据库 Nacos默认数据存储在内嵌数据库Derby中&#xff0c;不属于生产可用的数据库。官方推荐的使用mysql数据库&#xff0c;推荐使用数据库集群或者高可用数据库。 首先新建一个数据库&#xff0c;命名为nacos&#xff0c;而后导入下面的SQL&#xff08;直…

智慧工地源码 数字孪生可视化大屏 工地管理平台系统源码 多端展示(PC端、手机端、平板端)

智慧工地源码 数字孪生可视化大屏 工地管理平台系统源码 多端展示&#xff08;PC端、手机端、平板端&#xff09; 智慧工地系统多端展示&#xff08;PC端、手机端、平板端&#xff09;;数字孪生可视化大屏&#xff0c;一张图掌握项目整体情况;使用轻量化模型&#xff0c;部署三…

ubuntu22.04配置Azure Kinect DK深度相机

一.安装SDK 今天我来配置一下微软公司的Azure Kinect DK深度相机,以前在ubuntu18.04上配置过,因为官方说唯一支持linux版本是18.04,所以在18.04中配置还算顺利 but这不代表不可以在更高版本的ubuntu中使用,只不过需要自己去多配置一些东西 apt 源安装 更新源: c…

25.7 MySQL 数据库和表的基本操作

1. 基础知识 1.1 一条数据的存储过程 存储数据确实是处理数据的基石, 只有确保数据被准确无误且有条理地存储, 我们才能对其进行深入的处理和细致的分析. 否则, 这些数据就像是一团毫无章法的乱麻, 让我们难以捉摸其内在的逻辑和价值.那么, 如何才能够将用户那些与经营紧密相关…

VITIS更新硬件平台

VITIS硬件平台更新以后如何重新导入 在之前建立的硬件平台上右击&#xff0c;选择Update Hardware Specification&#xff0c;选择最新导出的硬件平台文件&#xff1b; 重建板级支持包 选择复位重建BSP源文件&#xff0c;俩个地方的BSP都Reset一下&#xff0c;然后Build&…

使用SqlDataAdapter和DataSet维护数据库表数据

使用SqlDataAdapter和DataSet维护数据库表数据一般按照如下步骤操作&#xff1a; 1.建立数据库连接 2.使用sql查询语句创建SqlDataAdapter实例&#xff0c;并利用SqlCommandBuilder自动生成SqlDataAdapter对象的InsertCommand&#xff0c;UpdateCommand&#xff0c;DeleteCom…

Transformer的前世今生 day08(Positional Encoding)

前情提要 Attention的优点&#xff1a;解决了长序列依赖问题&#xff0c;可以并行。Attention的缺点&#xff1a;开销变大了&#xff0c;而且不存在位置关系为了解决Attention中不存在位置关系的缺点&#xff0c;我们通过位置编码的形式加上位置关系 Positional Encoding&…

LinkedIn账号为什么被封?被封后如何解决?

近期会有一些小伙伴说自己遇到了帐号无法登录的情况&#xff0c;其实出现领英帐号被封号(被限制登录)主要会有两类情况&#xff0c;今天就给大家分享一下如果被封该如何解决&#xff0c;强烈建议收藏。 在电脑领英官网或者手机领英APP上&#xff0c;输入领英帐号密码点击登录后…

Python语法中,对函数名字的定义应该遵循什么规则?

在Python语法中&#xff0c;函数名字的定义应遵循以下规则&#xff1a; 标识符命名规则&#xff1a;函数名是一个标识符&#xff0c;因此它必须遵循Python的标识符命名规则。函数名只能包含字母&#xff08;A-Z&#xff0c;a-z&#xff09;、数字&#xff08;0-9&#xff09;和…

NDI虚拟摄像头的使用

目录 一、软件 二、具体操作 1、启动ScreenCapture 2、启动Webcam 3、选择NDI“源”

系统学习Python——装饰器:“私有“和“公有“属性案例-[验证函数的参数:针对位置参数的一个基本范围测试装饰器]

分类目录&#xff1a;《系统学习Python》总目录 让我们从基本的范围测试实现开始。为了简化步骤&#xff0c;起初我们将编写一个只对位置参数有效的装饰器&#xff0c;并且假设这些参数在每次调用中总是出现在相同的位置。位置参数不能通过关键字名称传递&#xff0c;并且我们在…

HCIP的学习(4)

GRE和MGRE VPN---虚拟专用网络。指依靠ISP&#xff08;运营商&#xff09;或其他公有网络基础设施上构建的专用的安全数据通信网络。该网络是属于逻辑上的。​ 核心机制—隧道机制&#xff08;封装技术&#xff09; GRE—通用路由封装 ​ 三层隧道技术&#xff0c;并且是属于…

代码随想录 图论

目录 797.所有可能得路径 200.岛屿数量 695.岛屿的最大面积 1020.飞地的数量 130.被围绕的区域 417.太平洋大西洋水流问题 827.最大人工岛 127.单词接龙 841.钥匙和房间 463.岛屿的周长 797.所有可能得路径 797. 所有可能的路径 中等 给你一个有 n 个节点的…