防止 JavaScript 中的正则表达式回溯

防止 JavaScript 中的正则表达式回溯

正则表达式是用于在软件应用程序中操作和验证文本的强大工具。然而,某些正则表达式模式可能容易受到回溯的影响,这可能会导致超线性运行时,并可能导致DoS攻击。在本文中,我们将探讨什么是回溯、它如何导致性能问题以及如何在正则表达式中防止回溯。

正则表达式中的回溯是什么

回溯是正则表达式引擎用来处理包含可选或重复子模式的复杂模式的技术。当正则表达式模式包含可选或重复的子模式时,引擎可能需要尝试子模式的多种组合才能找到匹配项。这个过程称为回溯。

例如,有以下正则表达式:

/^[a-zA-Z0-9\s]+$/

此正则表达式应匹配仅包含字母数字字符和空格的任何字符串。然而,它很容易受到回溯的影响,因为+字符类后面的运算符允许字符类的任意数量的重复。

攻击者可以通过发送包含一长串不匹配字符的恶意搜索查询来利用此漏洞,例如:

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaab

该字符串包含 30 个a字符,后跟一个b. 当正则表达式引擎尝试匹配该字符串时,它将前 30 个a字符与字符类匹配,但无法匹配b字符。然后,引擎将回溯并尝试字符类的不同组合,直到匹配整个字符串或耗尽所有可能的组合。

在本例中,字符串中有 31 个字符,因此有 2 种可能的字符类组合可供尝试。这可能需要很长的时间,可能会导致服务器遭受 DoS 攻击。

为了防止此漏洞,您可以修改正则表达式以使用*运算符代替+运算符,如下所示:

/^[a-zA-Z0-9\s]*$/

使用*可以使正则表达式不易受到回溯并降低 DoS 攻击的风险,因为它减少了正则表达式引擎需要探索的可能路径的数量。

+的意思是“一个或多个”,而*的意思是“零个或多个”。使用+时,正则表达式引擎必须在放弃之前尝试与模式匹配的所有可能的字符组合。这可能会导致回溯并导致引擎花费过多的时间来尝试匹配字符串,从而更容易受到 DoS 攻击。

另一方面,使用*使子模式成为可选,这意味着如果不匹配,正则表达式引擎可以完全跳过它。这减少了引擎需要探索的可能路径的数量。

回溯如何导致性能问题

回溯可能会通过两种方式导致性能问题:

  1. 超线性运行时间:回溯可能会导致正则表达式模式的运行时间变得超线性,这意味着匹配模式所需的时间增长速度快于输入字符串的长度。这可能会使该模式对于长输入字符串极其缓慢,并且如果将该模式应用于不受信任的用户输入,则可能会导致 DoS 攻击。
  2. 高内存使用量:回溯还会导致正则表达式引擎使用大量内存,特别是当模式包含嵌套的可选或重复的子模式时。这可能会导致应用程序内存不足并崩溃。

如何防止正则表达式模式中的回溯

为了防止正则表达式模式中的回溯,我们需要以避免可选或重复子模式的方式设计思路。以下是我们可以使用的一些技巧:

使用特定的字符类:

使用特定的字符类可以通过限制可以匹配子模式的字符数来帮助防止回溯。例如,/[a-z]/匹配从 az 的任何小写字母。

使用非捕获组

使用非捕获组可以通过避免不必要的内存分配来帮助防止回溯。例如,/(?:ab)+/匹配字符串ab的一次或多次出现,而不创建捕获组。

使用原子组

使用原子组可以通过使子模式成为非可选来帮助防止回溯。例如,/a(?>b|c)/匹配包含字母a后跟bc的字符串,而不进行回溯。

使用多个子模式而不将其中任何一个设为可选

使用多个子模式而不将其中任何一个设为可选可以通过限制正则表达式引擎需要探索的可能路径的数量来帮助防止回溯。例如,/^(ab|cd|ef)$/匹配abcdef字符串,而不进行回溯。

使用所有格子模式:

使用所有格子模式可以通过使子模式成为非可选来帮助防止回溯。所有格子模式由语法(?+...)表示。例如,/a(?+b)/匹配包含字母a后跟字母b的字符串,而不进行回溯。

使用惰性量词:

使用惰性量词可以通过使子模式可选来帮助防止回溯,但仍然可以防止回溯。惰性量词由+?or*?符号表示。例如,/a+?/匹配一​​次或多次出现的字母a,但使用惰性量词来防止回溯。

使用有界量词:

使用有界量词可以通过限制子模式的重复次数来帮助防止回溯。有界量词由语法{min,max}表示,其中minmax是指定最小和最大重复次数的整数。例如,/a{1,3}/匹配包含重复一到三次的字母a的字符串,而不回溯。

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

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

相关文章

ios swift5 collectionView 瀑布流(两列)

文章目录 1.瀑布流1.1 demo地址1.2 记得把部署的最低版本由8改成11,13甚至更高。不然编译会报错 2.动态计算图片和文字的高度 1.瀑布流 1.1 demo地址 CollectionViewWaterfallLayout - github 1.2 记得把部署的最低版本由8改成11,13甚至更高。不然编译会报错 2.动态计算图片和…

产业园区数字孪生3d可视化全景展示方案

随着数字经济的发展,数字技术给企业发展带来了机遇的同时,也为企业管理带来挑战。比如园区运维,不仅体量大,复杂的运维管理系统,落地难度也较高。那么如何通过数字化手段重塑园区运营,打通园区各业务数据孤…

SQLyog中导入CSV文件入库到MySQL中

1.在数据库中新建一个表,设置列名(与待导入文件一致),字段可以多出几个都可以 2.右键表名,导入- - >导入使用本地加载的CSV数据 选择使用加载本地CVS数据 3.指定好转义字符,将终止设置为,号(英文状态下…

idea常见错误大全之:解决全局搜索失效+搜索条件失效(条件为空)+F8失灵

问题一:全局搜索快捷键ctrlshiftf 突然失灵了,键盘敲烂了 都没反应,这是为什么呢? 肯定不是idea本身的原因,那么就是其它外在因素影响到了idea的快捷键,那么其它的快捷键为什么没失效呢,原因只有…

服务器扩展未生效

服务器扩容未生效 在阿里云付费扩容后,在服务器里面看未生效。 阿里云->实例与镜像->实例->选择实例->云盘->扩容进入linux服务器查看: df -h vda1扩容未生效。原40g->扩容后100g 解决方法: 1、安装growpart yum inst…

Win11环境下 Unity个人版无法激活

网上教程大多都是在win10环境下运行,win11环境下遇到很多没有碰到的问题,故简单做个记录,也方便同样使用win11的朋友解决问题。 Unity2021无法打开 问题描述:下载Unity2021.3.4f1c1版本(LTS)后&#xff0…

广州华锐互动:奶牛难产原因及救治VR仿真实训系统

奶牛难产是一种常见的疾病,对奶牛的健康和生产造成很大的影响。为了解决这一问题,许多奶牛养殖场开始采用VR仿真技术来培训奶牛兽医,帮助学生更好地理解奶牛养殖的实际过程,提高他们的实践能力的教学方式。 VR技术开发公司广州华锐…

【算法】双指针划分思想妙解移动零

Problem: 283. 移动零 文章目录 思路算法图解分析复杂度Code 思路 首先我们来讲一下本题的思路 本题主要可以归到【数组划分/数组分块】这一类的题型。我们将一个数组中的所有元素划分为两段区间,左侧是非零元素,右侧是零元素 那解决这一类的题我们首先想…

掌握指针进阶:一篇带你玩转函数指针、函数指针数组及指向函数指针数组的指针!!

🍁博客主页:江池俊的博客 💫收录专栏:C语言进阶之路 💡代码仓库:江池俊的代码仓库 🎪我的社区:GeekHub 🎉欢迎大家点赞👍评论📝收藏⭐ 文章目录 一…

基于Servlet实现的管理系统(包含服务器源码+数据库)

资料下载链接 介绍 基于Servlet框架的管理系统 简洁版 ; 实现 登录 、 注册 、 增 、 删 、 改 、 查 ; 可继续完善增加前端、校验、其他功能等; 可作为 Servlet项目 开发练习基础模型; 课程设计 、 毕业设计 开发基础&…

JVM---jvm里的内存溢出

目录 堆溢出 虚拟机栈和本地方法栈溢出(栈溢出很少出现) 方法区和运行时常量池溢出 本机内存直接溢出(实际中很少出现、了解即可) 堆溢出 堆溢出:最常见的是大list,list里面有很多元素 堆溢出该怎么解决…

第7章:贝叶斯分类器

贝叶斯决策论 贝叶斯分类器:使用贝叶斯公式 贝叶斯学习:使用分布估计(不同于频率主义的点估计) 极大似然估计 朴素贝叶斯分类 半朴素贝叶斯 条件独立性假设,在现实生活中往往很难成立。 半朴素贝叶 斯的一个常用策略…

C++学习笔记4

什么是指针? 指针是存储内存地址的变量。就像int变量用于存储整数值一样,指针变量用于存储内存地址。指针是一种指向内存单元的特殊变量。 内存单元地址通常使用的是16进制表示(0~9和A~F)来表示数字。显示…

React源码解析18(6)------ 实现useState

摘要 在上一篇文章中,我们已经实现了函数组件。同时可以正常通过render进行渲染。 而通过之前的文章,beginWork和completeWork也已经有了基本的架子。现在我们可以去实现useState了。 实现之前,我们要先修改一下我们的index.js文件&#x…

DAY2,ARM(特殊功能寄存器,数据操作指令,跳转指令)

1.cmp、sub、b指令的使用; 代码: .text .global _start _start:mov r0,#9mov r1,#15loop:cmp r0,r1beq stopsubcc r1,r1,r0subhi r0,r0,r1b loopstop:b stop .end结果: 2.汇编指令计算1~100之间和; 代码: .text .gl…

【从零学习python 】47. 面向对象编程中的继承概念及基本使用

文章目录 继承的基本使用代码逐行讲解说明:进阶案例 继承的基本使用 在现实生活中,继承一般指的是子女继承父辈的财产,父辈有的财产,子女能够直接使用。 程序里的继承 继承是面向对象软件设计中的一个概念,与多态、封装共为面向对…

Android 13 Launcher——屏蔽上拉到应用列表

背景 Launcher定制需要将原先的应用列表去掉,可以从根源去掉,就是将上拉出现应用列表的上拉手势直接屏蔽,让其不能上拉出现应用列表界面,在研究的过程中顺便将下拉出现负一屏的逻辑也研究了下,如下就是具体实现。 目录 背景 一.如何屏蔽上拉出现应用列表 一.如何屏蔽上拉…

培训报名小程序-用户注册

目录 1 创建数据源2 注册用户3 判断用户是否注册4 完整代码总结 我们的培训报名小程序,用户每次打开时都需要填写个人信息才可以报名,如果用户多次报名课程,每次都需要填写个人信息,比较麻烦。 本篇我们就优化一下功能&#xff0c…

线上售楼vr全景看房成为企业数字化营销工具

在房地产业中,VR全景拍摄为买家提供了虚拟看房的全新体验。买家可以通过相关设备,远程参观各个楼盘的样板间和实景,感受房屋的空间布局和环境氛围,极大地提高了购房决策的准确性。对于房地产开发商和中介机构来说,VR全…

@Async用哪个线程池

一共可以分三种情况 第一种 未在手动在项目中配置任何线程池 spring boot 会默认添加一个coreSize8的 无界线程池,名称为applicationTaskExecutor (源码:org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration&…