springCloud gateway 防止XSS漏洞

springCloud gateway 防止XSS漏洞

  • 一.XSS(跨站脚本)漏洞详解
    • 1.XSS的原理和分类
    • 2.XSS漏洞的危害
    • 3.XSS的防御
  • 二.Java开发中防范XSS跨站脚本攻击的思路
  • 三.相关代码(适用于spring cloud gateway)
    • 1.CacheBodyGlobalFilter.java
    • 2.XssRequestGlobalFilter.java
    • 3.XssResponseGlobalFilter.java
    • 4.XssCleanRuleUtils.java
    • 5.注意启动类不要忘记加@ComponentScan
  • 四.参考文章

一.XSS(跨站脚本)漏洞详解

1.XSS的原理和分类

跨站脚本攻击XSS(Cross Site Scripting),为了不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS。恶意攻击者往Web页面里插入恶意Script代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而达到恶意攻击用户的目的。XSS攻击针对的是用户层面的攻击!

XSS分为:存储型 、反射型 、DOM型XSS

在这里插入图片描述
在这里插入图片描述

  • 存储型XSS:存储型XSS,持久化,代码是存储在服务器中的,如在个人信息或发表文章等地方,插入代码,如果没有过滤或过滤不严,那么这些代码将储存到服务器中,用户访问该页面的时候触发代码执行。这种XSS比较危险,容易造成蠕虫,盗窃cookie

  • 反射型XSS:非持久化,需要欺骗用户自己去点击链接才能触发XSS代码(服务器中没有这样的页面和内容),一般容易出现在搜索页面

  • DOM型XSS:不经过后端,DOM-XSS漏洞是基于文档对象模型(Document Objeet Model,DOM)的一种漏洞,DOM-XSS是通过url传入参数去控制触发的,其实也属于反射型XSS。

2.XSS漏洞的危害

从以上我们可以知道,存储型的XSS危害最大。因为他存储在服务器端,所以不需要我们和被攻击者有任何接触,只要被攻击者访问了该页面就会遭受攻击。而反射型和DOM型的XSS则需要我们去诱使用户点击我们构造的恶意的URL,需要我们和用户有直接或者间接的接触,比如利用社会工程学或者利用在其他网页挂马的方式。

在这里插入图片描述

3.XSS的防御

XSS防御的总体思路是:对用户的输入(和URL参数)进行过滤,对输出进行html编码。也就是对用户提交的所有内容进行过滤,对url中的参数进行过滤,过滤掉会导致脚本执行的相关内容;然后对动态输出到页面的内容进行html编码,使脚本无法在浏览器中执行。

对输入的内容进行过滤,可以分为黑名单过滤和白名单过滤。黑名单过滤虽然可以拦截大部分的XSS攻击,但是还是存在被绕过的风险。白名单过滤虽然可以基本杜绝XSS攻击,但是真实环境中一般是不能进行如此严格的白名单过滤的。

对输出进行html编码,就是通过函数,将用户的输入的数据进行html编码,使其不能作为脚本运行。

如下,是使用php中的htmlspecialchars函数对用户输入的name参数进行html编码,将其转换为html实体

#使用htmlspecialchars函数对用户输入的name参数进行html编码,将其转换为html实体
$name = htmlspecialchars( $_GET[ 'name' ] );

二.Java开发中防范XSS跨站脚本攻击的思路

    1. 防堵跨站漏洞
      阻止攻击者利用在被攻击网站上发布跨站攻击语句不可以信任用户提交的任何内容,首先代码里对用户输入的地方和变量都需要仔细检查长度和对”<”,”>”,”;”,”’”等字符做过滤;其次任何内容写到页面之前都必须加以encode,避免不小心把html tag 弄出来。这一个层面做好,至少可以堵住超过一半的XSS 攻击。
    1. Cookie 防盗
      首先避免直接在cookie 中泄露用户隐私,例如email、密码等等。其次通过使cookie 和系统ip 绑定来降低cookie 泄露后的危险。这样攻击者得到的cookie 没有实际价值,不可能拿来重放。
    1. 尽量采用POST 而非GET 提交表单
      POST 操作不可能绕开javascript 的使用,这会给攻击者增加难度,减少可利用的跨站漏洞。
    1. 严格检查refer
      检查http refer 是否来自预料中的url。这可以阻止第2 类攻击手法发起的http 请求,也能防止大部分第1 类攻击手法,除非正好在特权操作的引用页上种了跨站访问。
    1. 将单步流程改为多步,在多步流程中引入效验码
      多步流程中每一步都产生一个验证码作为hidden 表单元素嵌在中间页面,下一步操作时这个验证码被提交到服务器,服务器检查这个验证码是否匹配。
      首先这为第1 类攻击者大大增加了麻烦。其次攻击者必须在多步流程中拿到上一步产生的效验码才有可能发起下一步请求,这在第2 类攻击中是几乎无法做到的。
    1. 引入用户交互
      简单的一个看图识数可以堵住几乎所有的非预期特权操作。
    1. 只在允许anonymous 访问的地方使用动态的javascript。
    1. 对于用户提交信息的中的img 等link,检查是否有重定向回本站、不是真的图片等可疑操作。
    1. 内部管理网站的问题

很多时候,内部管理网站往往疏于关注安全问题,只是简单的限制访问来源。这种网站往往对XSS 攻击毫无抵抗力,需要多加注意。安全问题需要长期的关注,从来不是一锤子买卖。XSS 攻击相对其他攻击手段更加隐蔽和多变,和业务流程、代码实现都有关系,不存在什么一劳永逸的解决方案。此外,面对XSS,往往要牺牲产品的便利性才能保证完全的安全,如何在安全和便利之间平衡也是一件需要考虑的事情。

web应用开发者注意事项:

  • 1.对于开发者,首先应该把精力放到对所有用户提交内容进行可靠的输入验证上。这些提交内容包括URL、查询关键字、http头、post数据等。只接受在你所规定长度范围内、采用适当格式、你所希望的字符。阻塞、过滤或者忽略其它的任何东西。
  • 2.保护所有敏感的功能,以防被bots自动化或者被第三方网站所执行。实现session标记(session tokens)、CAPTCHA系统或者HTTP引用头检查。
  • 3.如果你的web应用必须支持用户提供的HTML,那么应用的安全性将受到灾难性的下滑。但是你还是可以做一些事来保护web站点:确认你接收的HTML内容被妥善地格式化,仅包含最小化的、安全的tag(绝对没有JavaScript),去掉任何对远程内容的引用(尤其是样式表和JavaScript)。为了更多的安全,请使用httpOnly的cookie。

三.相关代码(适用于spring cloud gateway)

在这里插入图片描述

代码执行顺序
CacheBodyGlobalFilter—>XssRequestGlobalFilter—>XssResponseGlobalFilter

1.CacheBodyGlobalFilter.java

这个过滤器解决body不能重复读的问题(在低版本的spring-cloud不需要这个过滤器),为后续的XssRequestGlobalFilter重写请求body做准备

package com.xxx.gateway.filter;import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;/*** @Author:* @Description: 这个过滤器解决body不能重复读的问题,为后续的XssRequestGlobalFilter重写post|put请求的body做准备* @Date:* <p>* 没把body的内容放到attribute中去,因为从attribute取出body内容还是需要强转成 Flux<DataBuffer>,然后转换成String,和直接读取body没有什么区别*/
@Component
public class CacheBodyGlobalFilter implements Ordered, GlobalFilter {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {HttpMethod method = exchange.getRequest().getMethod();String contentType = exchange.getRequest().getHeaders().getFirst(HttpHeaders.CONTENT_TYPE);if (method == HttpMethod.POST || method == HttpMethod.PUT) {if (MediaType.APPLICATION_FORM_URLENCODED_VALUE.equalsIgnoreCase(contentType)|| MediaType.APPLICATION_JSON_VALUE.equalsIgnoreCase(contentType)|| MediaType.APPLICATION_JSON_UTF8_VALUE.equals(contentType)) {return DataBufferUtils.join(exchange.getRequest().getBody()).flatMap(dataBuffer -> {DataBufferUtils.retain(dataBuffer);Flux<DataBuffer> cachedFlux = Flux.defer(() -> Flux.just(dataBuffer.slice(0, dataBuffer.readableByteCount())));ServerHttpRequest mutatedRequest = new ServerHttpRequestDecorator(exchange.getRequest()) {@Overridepublic Flux<DataBuffer> getBody() {return cachedFlux;}};return chain.filter(exchange.mutate().request(mutatedRequest).build());});}}return chain.filter(exchange);}@Overridepublic int getOrder() {return Ordered.HIGHEST_PRECEDENCE;}
}

2.XssRequestGlobalFilter.java

自定义防XSS攻击网关全局过滤器。

package com.xxx.gateway.filter;import io.netty.buffer.ByteBufAllocator;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.core.io.buffer.NettyDataBufferFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.util.UriComponentsBuilder;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;import java.net.URI;
import java.nio.CharBuffer;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.atomic.AtomicReference;
/*** @Author:* @Description: 自定义防XSS攻击网关全局过滤器* @Date:*/@Component
public class XssRequestGlobalFilter implements GlobalFilter, Ordered {private Logger logger = LoggerFactory.getLogger(XssRequestGlobalFilter.class);/**** @param exchange* @param chain* @return** get请求参考spring cloud gateway自带过滤器:* @see org.springframework.cloud.gateway.filter.factory.AddRequestParameterGatewayFilterFactory** post请求参考spring cloud gateway自带过滤器:* @see org.springframework.cloud.gateway.filter.factory.rewrite.ModifyRequestBodyGatewayFilterFactory*/@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain){// grab configuration from Config objectlogger.info("----自定义防XSS攻击网关全局过滤器生效----");ServerHttpRequest serverHttpRequest = exchange.getRequest();HttpMethod method = serverHttpRequest.getMethod();String contentType = serverHttpRequest.getHeaders().getFirst(HttpHeaders.CONTENT_TYPE);Boolean postFlag = (method == HttpMethod.POST || method == HttpMethod.PUT) &&(MediaType.APPLICATION_FORM_URLENCODED_VALUE.equalsIgnoreCase(contentType) || MediaType.APPLICATION_JSON_VALUE.equals(contentType) || MediaType.APPLICATION_JSON_UTF8_VALUE.equals(contentType));// get 请求, 参考的是 org.springframework.cloud.gateway.filter.factory.AddRequestParameterGatewayFilterFactoryif (method == HttpMethod.GET) {URI uri = exchange.getRequest().getURI();String rawQuery = uri.getRawQuery();if (StringUtils.isBlank(rawQuery)){return chain.filter(exchange);}rawQuery = XssCleanRuleUtils.xssClean(rawQuery);try {URI newUri = UriComponentsBuilder.fromUri(uri).replaceQuery(rawQuery).build(true).toUri();ServerHttpRequest request = exchange.getRequest().mutate().uri(newUri).build();return chain.filter(exchange.mutate().request(request).build());} catch (Exception e) {logger.error("get请求清理xss攻击异常", e);throw new IllegalStateException("Invalid URI query: \"" + rawQuery + "\"");}}//post请求时,如果是文件上传之类的请求,不修改请求消息体else if (postFlag){// 参考的是 org.springframework.cloud.gateway.filter.factory.AddRequestParameterGatewayFilterFactory//从请求里获取Post请求体String bodyStr = resolveBodyFromRequest(serverHttpRequest);// 这种处理方式,必须保证post请求时,原始post表单必须有数据过来,不然会报错if (StringUtils.isBlank(bodyStr)) {logger.error("请求异常:{} POST请求必须传递参数", serverHttpRequest.getURI().getRawPath());ServerHttpResponse response = exchange.getResponse();response.setStatusCode(HttpStatus.BAD_REQUEST);byte[] bytes = "{\"code\":400,\"msg\":\"post data error\"}".getBytes(StandardCharsets.UTF_8);DataBuffer buffer = response.bufferFactory().wrap(bytes);return response.writeWith(Mono.just(buffer));}bodyStr = XssCleanRuleUtils.xssClean(bodyStr);URI uri = serverHttpRequest.getURI();URI newUri = UriComponentsBuilder.fromUri(uri).build(true).toUri();ServerHttpRequest request = exchange.getRequest().mutate().uri(newUri).build();DataBuffer bodyDataBuffer = stringBuffer(bodyStr);Flux<DataBuffer> bodyFlux = Flux.just(bodyDataBuffer);// 定义新的消息头HttpHeaders headers = new HttpHeaders();headers.putAll(exchange.getRequest().getHeaders());// 由于修改了传递参数,需要重新设置CONTENT_LENGTH,长度是字节长度,不是字符串长度int length = bodyStr.getBytes().length;headers.remove(HttpHeaders.CONTENT_LENGTH);headers.setContentLength(length);// 设置CONTENT_TYPEif (StringUtils.isNotBlank(contentType)) {headers.set(HttpHeaders.CONTENT_TYPE, contentType);}// 由于post的body只能订阅一次,由于上面代码中已经订阅过一次body。所以要再次封装请求到request才行,不然会报错请求已经订阅过request = new ServerHttpRequestDecorator(request) {@Overridepublic HttpHeaders getHeaders() {long contentLength = headers.getContentLength();HttpHeaders httpHeaders = new HttpHeaders();httpHeaders.putAll(super.getHeaders());if (contentLength > 0) {httpHeaders.setContentLength(contentLength);} else {// this causes a 'HTTP/1.1 411 Length Required' on httpbin.orghttpHeaders.set(HttpHeaders.TRANSFER_ENCODING, "chunked");}return httpHeaders;}@Overridepublic Flux<DataBuffer> getBody() {return bodyFlux;}};//封装request,传给下一级request.mutate().header(HttpHeaders.CONTENT_LENGTH, Integer.toString(bodyStr.length()));return chain.filter(exchange.mutate().request(request).build());} else {return chain.filter(exchange);}}@Overridepublic int getOrder() {return -90;}/*** 从Flux<DataBuffer>中获取字符串的方法* @return 请求体*/private String resolveBodyFromRequest(ServerHttpRequest serverHttpRequest) {//获取请求体Flux<DataBuffer> body = serverHttpRequest.getBody();AtomicReference<String> bodyRef = new AtomicReference<>();body.subscribe(buffer -> {CharBuffer charBuffer = StandardCharsets.UTF_8.decode(buffer.asByteBuffer());DataBufferUtils.release(buffer);bodyRef.set(charBuffer.toString());});//获取request bodyreturn bodyRef.get();}/*** 字符串转DataBuffer* @param value* @return*/private DataBuffer stringBuffer(String value) {byte[] bytes = value.getBytes(StandardCharsets.UTF_8);NettyDataBufferFactory nettyDataBufferFactory = new NettyDataBufferFactory(ByteBufAllocator.DEFAULT);DataBuffer buffer = nettyDataBufferFactory.allocateBuffer(bytes.length);buffer.write(bytes);return buffer;}
}

3.XssResponseGlobalFilter.java

重写Response,防止xss攻击。

package com.xxx.gateway.filter;import org.reactivestreams.Publisher;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.http.server.reactive.ServerHttpResponseDecorator;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;import java.nio.charset.Charset;
import java.util.Arrays;/*** @Author:* @Description: 重写Response,防止xss攻击* @Date:*/
@Component
public class XssResponseGlobalFilter implements Ordered, GlobalFilter {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {//获取请求urlString path = exchange.getRequest().getPath().toString();//声明带有富文本的接口数组String[] richTextUrls = {"/xxx/findByUnid"};ServerHttpResponse originalResponse = exchange.getResponse();DataBufferFactory bufferFactory = originalResponse.bufferFactory();ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(originalResponse) {@Overridepublic Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {String contentType = getDelegate().getHeaders().getFirst(HttpHeaders.CONTENT_TYPE);Boolean flag = MediaType.APPLICATION_JSON_VALUE.equals(contentType) || MediaType.APPLICATION_JSON_UTF8_VALUE.equals(contentType);if (body instanceof Flux && flag) {Flux<? extends DataBuffer> fluxBody = (Flux<? extends DataBuffer>) body;return super.writeWith(fluxBody.map(dataBuffer -> {// probably should reuse buffersbyte[] content = new byte[dataBuffer.readableByteCount()];dataBuffer.read(content);//释放掉内存DataBufferUtils.release(dataBuffer);String result = new String(content, Charset.forName("UTF-8"));//若为带有富文本的接口,走富文本xss过滤if (Arrays.asList(richTextUrls).contains(path)) {result = XssCleanRuleUtils.xssRichTextClean(result);} else {//result就是response的值,对result进行去XSSresult = XssCleanRuleUtils.xssClean(result);}byte[] uppedContent = new String(result.getBytes(), Charset.forName("UTF-8")).getBytes();return bufferFactory.wrap(uppedContent);}));}// if body is not a flux. never got there.return super.writeWith(body);}};// replace response with decoratorreturn chain.filter(exchange.mutate().response(decoratedResponse).build());}@Overridepublic int getOrder() {return -50;}
}

4.XssCleanRuleUtils.java

上面几个过滤器使用的工具类

package com.xxx.gateway.filter;import java.util.regex.Pattern;/*** @Author:* @Description: xss过滤工具* @Date:*/
public class XssCleanRuleUtils {//过滤规则private final static Pattern[] scriptPatterns = {Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE),Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),Pattern.compile("</script>", Pattern.CASE_INSENSITIVE),Pattern.compile("<script(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),Pattern.compile("eval\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),Pattern.compile("expression\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE),Pattern.compile("vbscript:", Pattern.CASE_INSENSITIVE),Pattern.compile("onload(.*?)=", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL)};public static String xssClean(String value) {if (value != null) {value = value.replaceAll("\0|\n|\r", "");for (Pattern pattern : scriptPatterns) {value = pattern.matcher(value).replaceAll("");}value = value.replaceAll("<", "&lt;").replaceAll(">", "&gt;");}return value;}//富文本的过滤规则(不转义"<"、">")//不然会导致富文本无法显示的内容样式)public static String xssRichTextClean(String value) {if (value != null) {value = value.replaceAll("\0|\n|\r", "");for (Pattern pattern : scriptPatterns) {value = pattern.matcher(value).replaceAll("");}}return value;}
}

5.注意启动类不要忘记加@ComponentScan

在这里插入图片描述

四.参考文章

【1】spring cloud gateway 过滤器防止跨站脚本攻击(存储XSS、反射XSS)
https://blog.csdn.net/qq_26801767/article/details/106235359?utm_medium=distribute.pc_relevant.none-task-blog-2defaultbaidujs_baidulandingword~default-4-106235359-blog-128300551.235v40pc_relevant_3m_sort_dl_base1&spm=1001.2101.3001.4242.3&utm_relevant_index=7
【2】XSS(跨站脚本)漏洞详解之XSS跨站脚本攻击漏洞的解决
http://www.uml.org.cn/safe/202203034.asp
【3】SpringCloud微服务实战——搭建企业级开发框架(五十一):微服务安全加固—自定义Gateway拦截器实现防止SQL注入/XSS攻击
https://blog.csdn.net/wmz1932/article/details/129449794
【4】Spring Cloud Gateway 实现XSS、SQL注入拦截
https://www.jianshu.com/p/17613323463d
【5】SpringBoot针对富文本和非富文本添加xss过滤
https://blog.csdn.net/ChOLg/article/details/119949942
【6】详解Xss 及SpringBoot 防范Xss攻击(附全部代码)
https://www.cnblogs.com/blbl-blog/p/17188558.html

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

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

相关文章

强大的虚拟机Parallels Desktop 19 mac中文激活

Parallels Desktop是一款功能全面、易于使用的虚拟机软件&#xff0c;它为用户提供了在Mac电脑上同时运行多个操作系统的便利。 软件下载&#xff1a;Parallels Desktop 19 mac中文激活版下载 Parallels Desktop 19 mac具有快速启动和关闭虚拟机的能力&#xff0c;让用户能够迅…

STM32G4 系列命名规则

STM32G4产品线 基础型系列STM32G4x1 具有入门级模拟外设配置&#xff0c;单存储区Flash&#xff0c;支持的Flash存储器容量范围从32到512KB。 增强型系列STM32G4x3 与基本型器件相比具有更多数量的模拟外设&#xff0c;以及双存储区Flash&#xff0c;Flash存储器容量也提高…

C#学习笔记_类(Class)

类的定义 类的定义是以关键字 class 开始&#xff0c;后跟类的名称。类的主体&#xff0c;包含在一对花括号内。 语法格式如下&#xff1a; 访问标识符 class 类名 {//变量定义访问标识符 数据类型 变量名;访问标识符 数据类型 变量名;访问标识符 数据类型 变量名;......//方…

【Day37】代码随想录之贪心_738.单调递增的数字_968.监控二叉树

文章目录 738.单调递增的数字968.监控二叉树 738.单调递增的数字 参考文档&#xff1a;代码随想录 题目&#xff1a; 给定一个非负整数 N&#xff0c;找出小于或等于 N 的最大的整数&#xff0c;同时这个整数需要满足其各个位数上的数字是单调递增。 &#xff08;当且仅当每个相…

你的MiniFilter安全吗?

简介 筛选器管理器 (FltMgr.sys)是Windows系统提供的内核模式驱动程序, 用于实现和公开文件系统筛选器驱动程序中通常所需的功能; 第三方文件系统筛选器开发人员可以使用FltMgr的功能可以更加简单的编写文件过滤驱动, 这种驱动我们通常称为MiniFilter, 下面是MiniFilter的基本…

基于SpringBoot+Vue学科竞赛管理系统

文章目录 基于SpringBootVue学科竞赛管理系统1系统概述1.3系统设计思想 2相关技术2.1 MYSQL数据库2.2 B/S结构2.3 Spring Boot框架简介2.4 Vue简介 3系统分析3.1可行性分析3.1.1技术可行性3.1.2经济可行性3.1.3操作可行性 3.2系统性能分析3.2.1 系统安全性3.2.2 数据完整性 3.4…

【2024】大三寒假再回首:缺乏自我意识是毒药,反思和回顾是解药

2024年初&#xff0c;学习状态回顾 开稿时间&#xff1a;2024-1-23 归家百里去&#xff0c;飘雪送客迟。 搁笔日又久&#xff0c;一顾迷惘时。 我们饱含着过去的习惯&#xff0c;缺乏自我意识是毒药&#xff0c;反思和回顾是解药。 文章目录 2024年初&#xff0c;学习状态回顾一…

虚拟机(VMware)ubuntu16.04 直接连接网口设备 USRP 吊舱

编辑虚拟网络编辑器 点击之后 选择网卡之后&#xff0c;点击确定。 电脑配置 使用了&#xff1a;192.168.2.56 虚拟机内部配置 和PC的配置一致

【Matlab】音频信号分析及FIR滤波处理——凯泽(Kaiser)窗

一、前言 1.1 课题内容: 利用麦克风采集语音信号(人的声音、或乐器声乐),人为加上环境噪声(窄带)分析上述声音信号的频谱,比较两种情况下的差异根据信号的频谱分布,选取合适的滤波器指标(频率指标、衰减指标),设计对应的 FIR 滤波器实现数字滤波,将滤波前、后的声音…

Zoho Mail 2023:回顾过去,展望未来:不断进化的企业级邮箱解决方案

当我们告别又一个非凡的一年时&#xff0c;我们想回顾一下Zoho Mail如何融合传统与创新。我们迎来了成立15周年&#xff0c;这是一个由客户、合作伙伴和我们的敬业团队共同庆祝的里程碑。与我们一起回顾这段旅程&#xff0c;探索定义Zoho Mail历史篇章的敏捷性、精确性和创新性…

Spring 事务原理二

该说些什么呢&#xff1f;一连几天&#xff0c;我都沉溺在孤芳自赏的思维中无法自拔。不知道自己为什么会有这种令人不齿的表现&#xff0c;更不知道这颗定时炸弹何时会将人炸的粉身碎骨。好在儒派宗师曾老夫子“吾日三省吾身”的名言警醒了我。遂潜心自省&#xff0c;溯源头以…

C++初阶入门之命名空间和缺省参数的详细解析

个人主页&#xff1a;点我进入主页 专栏分类&#xff1a;C语言初阶 C语言进阶 数据结构初阶 Linux C初阶 欢迎大家点赞&#xff0c;评论&#xff0c;收藏。 一起努力&#xff0c;一起奔赴大厂 目录 一.前言 二.命名空间 2.1命名冲突的例子 2.2解决方案 2.3命…

MyBatis概述与MyBatis入门程序

MyBatis概述与MyBatis入门程序 一、MyBatis概述二、入门程序1.准备开发环境&#xff08;1&#xff09;准备数据库&#xff08;2&#xff09;创建一个maven项目 2.编写代码&#xff08;1&#xff09;打包方式和引入依赖&#xff08;2&#xff09;新建mybatis-config.xml配置⽂件…

node.js(nest.js控制器)学习笔记

nest.js控制器&#xff1a; 控制器负责处理传入请求并向客户端返回响应。 为了创建基本控制器&#xff0c;我们使用类和装饰器。装饰器将类与所需的元数据相关联&#xff0c;并使 Nest 能够创建路由映射&#xff08;将请求绑定到相应的控制器&#xff09;。 1.获取get请求传参…

祖传代码里的神逻辑

昨天做权限限制的需求&#xff0c;给自己配置了两个新的分组&#xff0c;然后就发现登录不了项目了&#xff0c;sql报错ORA-01795: maximum number of expressions in a list is 1000&#xff0c;一路debugger找到了元凶&#xff0c;看逻辑是想把两个不同表里的分组去重然后合并…

【CMU-自主导航与规划】M-TARE planner 配置与运行

M-TARE docker M-TARE 源码 一、依赖 Docker, Docker Compose, NVIDIA Container Toolkit, Nvidia GPU Driver&#xff08;需要至少2个&#xff0c;带Nvidia GPU&#xff09; 1.1 Docker docker -v #查询版本1.2 Docker Compose docker compose version1.3 …

分布式搜索引擎_学习笔记_3

分布式搜索引擎03 0.学习目标 1.数据聚合 **聚合&#xff08;aggregations&#xff09;**可以让我们极其方便的实现对数据的统计、分析、运算。例如&#xff1a; 什么品牌的手机最受欢迎&#xff1f;这些手机的平均价格、最高价格、最低价格&#xff1f;这些手机每月的销售…

Here Document免交互和Expect

文章目录 Here Document免交互和Expect自动化交互一、Here Document—免交互1、Here Document 免交互概述2、语法格式3、免交互的用法3.1 cat命令3.2 tee命令3.3 wc命令3.4 read命令3.5 passwd命令 4、Here Document 变量设定 二、Expect自动化交互1、expect基本使用1.1 脚本解…

【Linux】Linux基本指令

目录 1.ls指令 2.cd指令 3.touch指令 4.mkdir指令 5.rmdir指令和rm指令 5.1rmdir指令 5.2rm指令 6.man指令 7.cp指令 8.mv指令 9.cat指令 10.more指令 && less指令 10.1more指令 10.2less指令 11.head指令 && tail指令 11.1head指令 11.2tai…

【数学】【记忆化搜索 】【动态规划】964. 表示数字的最少运算符

作者推荐 【动态规划】【字符串】【表达式】2019. 解出数学表达式的学生分数 本文涉及知识点 动态规划汇总 数学 记忆化搜索 LeetCoce964表示数字的最少运算符 给定一个正整数 x&#xff0c;我们将会写出一个形如 x (op1) x (op2) x (op3) x … 的表达式&#xff0c;其中每…