业务服务: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.rhkb.cn/news/287460.html

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

相关文章

代码随想录 图论-并查集

代码随想录 (programmercarl.com) 寻找图中是否存在路径这道题中的类可看做并查集的标准类 目录 1971.寻找图中是否存在路径 684.冗余连接 685.冗余连接II 1971.寻找图中是否存在路径 1971. 寻找图中是否存在路径 已解答 简单 相关标签 相关企业 有一个具有 n 个顶…

使用ai智能写作场景之gpt整理资料,如何ai智能写作整理资料

Ai智能写作助手&#xff1a;Ai智能整理资料小助手 Ai智能整理资料小助手可试用3天&#xff01; 通俗的解释一下怎么用ChatGPT来进行资料整理&#xff1a; 搜寻并获取指定数量的特定领域文章&#xff1a; 想像你在和我说话一样&#xff0c;告诉我你想要多少篇关于某个话题的文…

Flask python :logging日志功能使用

logging日志的使用 一、了解flask日志1.1、Loggers记录器1.2、Handlers 处理器1.3、Formatters 格式化器 二、使用日志2.1、官网上的一个简单的示例2.2、基本配置2.3、具体使用示例2.4、运行 三、写在最后 一、了解flask日志 日志是一种非常重要的工具&#xff0c;可以帮助开发…

【双指针】Leetcode 查找总价格为目标值的两个商品

题目解析 LCR 179. 查找总价格为目标值的两个商品 本题很友好&#xff0c;只需要返回任意一个 算法讲解 这道题很显然就是使用对撞双指针&#xff0c;一个从左边&#xff0c;一个从右边&#xff0c;两边进行和target比较来移动 代码编写 class Solution { public:vector<…

谷粒商城——缓存——SpringCache

1. 配置使用 首先需要导入相关的依赖&#xff1a; <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId></dependency> 随后在配置文件中进行配置&#xff1a; spring:cache:t…

C语言文件操作(详细)

⽬录 一. 为什么使⽤⽂件&#xff1f; 二. 什么是⽂件&#xff1f; 三. ⼆进制⽂件和⽂本⽂件&#xff1f; 四. ⽂件的打开和关闭 五. ⽂件的顺序读写 六. ⽂件的随机读写 七. ⽂件读取结束的判定 八. ⽂件缓冲区 一. 为什么使⽤⽂件&#xff1f; 如果没有⽂件&#…

STM32技术打造:智能考勤打卡系统 | 刷卡式上下班签到自动化解决方案

文章目录 一、简易刷卡式打卡考勤系统&#xff08;一&#xff09;功能简介原理图设计程序设计 哔哩哔哩&#xff1a; https://www.bilibili.com/video/BV1NZ421Y79W/?spm_id_from333.999.0.0&vd_sourcee5082ef80535e952b2a4301746491be0 一、简易刷卡式打卡考勤系统 &…

docker拉取镜像

docker 拉取镜像 命令格式 docker pull 仓库名称[:标签] 从下载过程可以看出&#xff1a; &#xff08;1&#xff09;镜像文件是由若干层组成&#xff0c;即&#xff1a;AUFS联合文件系统。这是实现增量保存与更新的基础 &#xff08;2&#xff09;下载过程会输出各层镜像的信…

界面控件DevExpress WinForms/WPF v23.2 - 电子表格支持表单控件

DevExpress WinForm拥有180组件和UI库&#xff0c;能为Windows Forms平台创建具有影响力的业务解决方案。DevExpress WinForm能完美构建流畅、美观且易于使用的应用程序&#xff0c;无论是Office风格的界面&#xff0c;还是分析处理大批量的业务数据&#xff0c;它都能轻松胜任…

String类(三)

文章目录 string类&#xff08;三&#xff09;string类的模拟实现&#xff1a;1.默认成员变量和函数2.string的长度和下表引用3.字符串拷贝构造4. 赋值拷贝5.字符串比较6.字符串的增添操作7.insert插入操作8.遍历字符 string类&#xff08;三&#xff09; string类的模拟实现&…

Django(二)-搭建第一个应用(1)

一、项目环境和结构 1、项目环境 2、项目结构 二、编写项目 1、创建模型 代码示例: import datetimefrom django.db import models from django.utils import timezone# Create your models here.class Question(models.Model):question_text models.CharField(max_length2…

ES6 基础

文章目录 1. 初识 ES62. let 声明变量3. const 声明常量4. 解构赋值 1. 初识 ES6 ECMAScript6.0(以下简称ES6)是JavaScript语言的下一代标准&#xff0c;已经在2015年6月正式发布了。它的目标&#xff0c;是使得」JavaScript语言可以用来编写复杂的大型应用程序&#xff0c;成为…

【环境配置】Ubuntu MySQL 8.0.28 安装并允许外部客户端连接

文章目录 MySQL 安装步骤配置 MySQL Server 允许外部连接 MySQL 安装步骤 步骤一&#xff1a;在 MySQL 官网找到 apt 仓库&#xff0c;下载最新的仓库 点击 Download&#xff1a; 输入如下命令&#xff1a; sudo wget -c https://dev.mysql.com/get/mysql-apt-config_0.8…

Java拆装箱及128陷阱

有以下一段代码&#xff1a; Integer a 123; Integer b 123; int c 123; int d 123; System.out.println(c d); System.out.println(a b); System.out.println(a c); 这段代码运行的结果是什么呢&#xff1f; c d 一定为True。 由于Java中存在自动拆装箱&#xff0…

【Spring】Spring框架中的一个核心接口ApplicationContext 简介,以及入口 Run() 的源码分析

一、简介 ApplicationContext 是Spring框架中的一个核心接口&#xff0c;它是Spring IoC容器的实现之一&#xff0c;用于管理和组织应用程序中的各种Bean&#xff0c;同时提供了一系列功能来支持依赖注入、AOP等特性。 简单来说&#xff0c;ApplicationContext 是一个大型的、…

如何备考2025年AMC8竞赛?吃透2000-2024年600道真题(免费送题)

最近有家长朋友问我&#xff0c;现在有哪些类似于奥数的比赛可以参加&#xff1f;我的建议可以关注下AMC8的竞赛&#xff0c;类似于国内的奥数&#xff0c;但是其难度要比国内的奥数低一些&#xff0c;而且比赛门槛更低&#xff0c;考试也更方便。比赛的题目尤其是应用题比较有…

FPGA之组合逻辑与时序逻辑

数字逻辑电路根据逻辑功能的不同&#xff0c;可以分成两大类&#xff1a;组合逻辑电路和时序逻辑电路&#xff0c;这两种电路结构是FPGA编程常用到的&#xff0c;掌握这两种电路结构是学习FPGA的基本要求。 1.组合逻辑电路 组合逻辑电路概念&#xff1a;任意时刻的输出仅仅取决…

2015年认证杯SPSSPRO杯数学建模B题(第一阶段)替换式密码全过程文档及程序

2015年认证杯SPSSPRO杯数学建模 B题 替换式密码 原题再现&#xff1a; 历史上有许多密码的编制方法。较为简单的是替换式密码&#xff0c;也就是将文中出现的字符一对一地替换成其它的符号。对拼音文字而言&#xff0c;最简单的形式是单字母替换加密&#xff0c;也就是以每个…

小迪安全48WEB 攻防-通用漏洞Py 反序列化链构造自动审计 bandit魔术方法

#知识点&#xff1a; 1、Python-反序列化函数使用 2、Python-反序列化魔术方法 3、Python-反序列化 POP 链构造&#xff08;payload构造&#xff09; 4、Python-自动化审计 bandit 使用 #前置知识&#xff1a; 函数使用&#xff1a; pickle.dump(obj, file) : 将对…

pycharm使用远程服务器的jupyter环境

1、确保服务器上安装了jupyter,如果没有&#xff0c;执行下面命令安装 pip install jupyter2、启动jupyter notebook服务 jupyter notebook --no-browser --port8888 --ip0.0.0.0 --allow-root表明在服务器的8888 端口上启动 Jupyter Notebook&#xff0c;并允许从任何 IP 地…