《探错笔记》之一个正则引发的血案:ReDOS
ReDoS(Regular expression Denial of Service) 正则表达式拒绝服务攻击。
开发人员使用了正则表达式来对用户输入的数据进行有效性校验, 当编写校验的正则表达式存在缺陷或者不严谨时, 攻击者可以构造特殊的字符串来大量消耗服务器的系统资源,造成服务器的服务中断或停止。
ReDoS 原理
概述
正则表达式也能造成拒绝服务?是的,当正则表达式写得不好时,就有可能被恶意输入利用,消耗大量资源,从而造成DOS.这种攻击被称为ReDOS。
正则表达式引擎分成两类:一类称为 DFA(确定性有限状态自动机) ,另一类称为 NFA(非确定性有限状态自动机) 。两类引擎要顺利工作,都必须有一个正则式和一个文本串,一个捏在手里,一个吃下去。
DFA 捏着文本串去比较正则式,看到一个子正则式,就把可能的匹配串全标注出来,然后再看正则式的下一个部分,根据新的匹配结果更新标注。
而 NFA 是捏着正则式去比文本,吃掉一个字符,就把它跟正则式比较,匹配就记下来:“某年某月某日在某处匹配上了!”,然后接着往下干。
一旦不匹配,就把刚吃的这个字符吐出来,一个个的吐,直到回到上一次匹配的地方。
部分程序及其所使用的正则引擎:
引擎类型 | 程序 |
---|---|
DFA | awk(大多数版本)、egrep(大多数版本)、flex、lex、MySQL、Procmail |
传统型 NFA | GNU Emacs、Java、grep(大多数版本)、less、more、.NET语言、PCRE library、Perl、PHP(所有三套正则库)、Python、Ruby、set(大多数版本)、vi |
POSIX NFA | mawk、Mortice Lern System’s utilities、GUN Emacs(明确指定时使用) |
DFA/NFA混合 | GNU awk、 GNU grep/egrep、 Tcl |
DFA 对于文本串里的每一个字符只需扫描一次,比较快,但特性较少; NFA 要翻来覆去吃字符、吐字符,速度慢,但是特性(如:分组、替换、分割)丰富。
NFA 支持 惰性(lazy) 、 回溯(backtracking) 、 反向引用(backreference) , NFA 缺省应用 greedy 模式, NFA 可能会陷入递归险境导致性能极差。
说明
ReDOS 是一种代码实现上的缺陷。我们知道正则表达式是基于NFA(Nondeterministic Finite Automaton)的,它是一个状态机, 每个状态和输入符号都可能有许多不同的下一个状态。 正则解析引擎将遍历所有可能的路径直到最后。由于每个状态都有若干个“下一个状态”,因此决策算法将逐个尝试每个“下一个状态”,直到找到一个匹配的。
我们定义一个正则表达式 ^(a+)+$ 来对字符串 aaaaX 匹配。使用 NFA 的正则引擎,必须经历 2^4=16 次尝试失败后才能否定这个匹配。
但是当输入以下字符串时:
aaaaaaaaaaaaaaaaX
就变成了65536条可能的路径;此后每增加一个“a”,路径的数量都会翻倍。
这极大地增加了正则引擎解析数据时的消耗。 当用户恶意构造输入时,这些有缺陷的正则
表达式就会消耗大量的系统资源(比如CPU和内存),从而
导致整台服务器的性能下降,表现
的结果是系统速度很慢,有的进程或服务失去响应, 与拒绝服务的后果是一样的。
总结
每个恶意的正则表达式模式应该包含:
- 使用重复分组构造
- 在重复组内会出现◦重复
- 交替重叠
有缺陷的正则表达式会包含如下部分:
•(a+)+
•([a-zA-Z]+)*
•(a|aa)+
•(a|a?)+
•(.*a){x} | for x > 10
注意: 这里的a是个泛指
部分实际业务场景中会用到的缺陷正则
英文的个人名字:◦Regex: ^[a-zA-Z]+(([\'\,\.\-][a-zA-Z ])?[a-zA-Z]*)*$
◦Payload: aaaaaaaaaaaaaaaaaaaaaaaaaaaa!•Java Classname◦Regex: ^(([a-z])+.)+[A-Z]([a-z])+$
◦Payload: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!•Email格式验证◦Regex: ^([0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*@(([0-9a-zA-Z])+([-\w]*[0-9a-zA-Z])*\.)+[a-zA-Z]{2,9})$
◦Payload: a@aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!•多个邮箱地址验证◦Regex: ^[a-zA-Z]+(([\'\,\.\-][a-zA-Z ])?[a-zA-Z]*)*\s+<(\w[-._\w]*\w@\w[-._\w]*\w\.\w{2,3})>$|^(\w[-._\w]*\w@\w[-._\w]*\w\.\w{2,3})$
◦Payload: aaaaaaaaaaaaaaaaaaaaaaaa!•复数验证◦Regex: ^\d*[0-9](|.\d*[0-9]|)*$
◦Payload: 1111111111111111111111111!•模式匹配◦Regex: ^([a-z0-9]+([\-a-z0-9]*[a-z0-9]+)?\.){0,}([a-z0-9]+([\-a-z0-9]*[a-z0-9]+)?){1,63}(\.[a-z0-9]{2,7})+$
◦Payload: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!
防范手段
防范手段只是为了降低风险而不能百分百消除 ReDoS 这种威胁。当然为了避免这种威胁的最好手段是尽量减少正则在业务中的使用场景或者多做测试, 增加服务器的性能监控等。
•降低正则表达式的复杂度, 尽量少用分组
•严格限制用户输入的字符串长度(特定情况下)
•使用单元测试、fuzzing 测试保证安全
•使用静态代码分析工具, 如: sonar
•添加服务器性能监控系统, 如: zabbix
关注Github:1/2极客
关注博客:御前提笔小书童
关注网站:HuMingfeng
关注公众号:开发者的花花世界
《探错笔记》之一个正则引发的血案:ReDOS相关推荐
- 《探错笔记》之Linux的FTP服务
Linux下FTP服务 FTP服务的安装和配置 FTP服务的安装和开启 添加用户配置权限和指定目录 FTP的配置详解 常见问题 启动vsftpd服务,报错:Job for vsftpd.service ...
- 《探错笔记》之挂载NFS时提示:mount: 文件系统类型错误、选项错误、有坏超级块
记一次同事服务器共享磁盘挂载不上报错的问题 linux系统进行磁盘挂载时,报错显示: # mount 172.19.4.12:/data/nfs /data/nfs mount: 文件系统类型错误.选 ...
- 探案笔记千万融资:剧本杀的喜与忧
如今,剧本杀已经成为年轻人的心头好.一方面是剧本杀通过角色扮演,能给玩家带来一段全新的人生体验:另一方面是因为剧本杀的团体氛围能够让玩家破除社恐,迅速熟络起来.剧本杀能带给玩家不一样的消费体验. 近日 ...
- 转:一个Sqrt函数引发的血案
转自:http://www.cnblogs.com/pkuoliver/archive/2010/10/06/1844725.html 源码下载地址:http://diducoder.com/sotr ...
- 一个普通ERROR 1135 (HY000)错误引发的血案:
一个普通ERROR 1135 (HY000)错误引发的血案: 今天接到测试人员反应,测试环境前端应用程序无连接mysql数据库,登录mysql服务器,查看错误日志,发现有如下报错: 点击(此处)折叠或 ...
- 线上 CPU100% 异常案例:一个正则表达式引发的血案
前几天线上一个项目监控信息突然报告异常,上到机器上后查看相关资源的使用情况,发现 CPU 利用率将近 100%.通过 Java 自带的线程 Dump 工具,我们导出了出问题的堆栈信息. 我们可以看到所 ...
- 一个由正则表达式引发的血案
阿里妹导读:周末快到了,今天为大家送上一篇很有意思的小文章,具有提神醒脑之功效.作者是来自阿里巴巴LAZADA产品技术部的申徒童鞋. 血案由来 近期我在为Lazada卖家中心做一个自助注册的项目,其中 ...
- 一个Sqrt函数引发的血案
我们平时经常会有一些数据运算的操作,需要调用sqrt,exp,abs等函数,那么时候你有没有想过:这个些函数系统是如何实现的?就拿最常用的sqrt函数来说吧,系统怎么来实现这个经常调用的函数呢? 虽然 ...
- ”一个馒头引发的血案“|记Mybatis之BindingException异常的产生及解决过程
一. 业务场景 前几天壹哥带学生做一个项目,需要更新数据库中的车辆信息表,具体需求是要根据指定车辆的设备id(编号和设备ID均非主键)来更新车辆信息.壹哥要求学生们用Mybatis进行实现,所以就在对 ...
最新文章
- Linux命令——cp
- 数组越界怎么判断_算法连载之求解两个有序数组的中位数
- 【Linux笔记】第七篇、配置MariaDB的字符集
- 索尼录音笔怎么导出录音内容_录音笔十大品牌名单出炉!录音笔十大品牌排名榜单揭晓!...
- linux 笔记之一mysql源码包安装
- 真实的布兰妮,有点壮
- PowerDesigner--创建业务流程模型
- [考试]20151008
- 4.4.4 无锁的对象引用:AtomicReference和AtomicStampedReference
- webpack配置时:Plugin/Preset files are not allowed to export objects, only functions.
- windows系统腾讯qq自带截图工具自动滚动截长图方法
- c语言 delphi,delphi和c语言的比较 极其粗浅 菜鸟共勉
- ESP8266串口透传+WiFi储存+OTA+smartconfig/airkiss
- Kubernetes (K8s) 安装部署过程(七)之部署node节点
- sim7600ce 拨号上网测试_SIM7600CE应用程序调试流程
- 秋招/春招常见笔试题目——二叉树系列(C/C++)
- 作为使用者如何应对JCenter远程仓库停止维护
- Python print 玩转点阵字
- 遇到空指针异常的时候我们应该怎么办
- 一本通1015:计算并联电阻的阻值
热门文章
- 用requestAnimationFrame替代setInterval制作匀速动画
- 用python识别条形码,二维码并且定位标注
- #边学边记 必修4 高项:对事的管理 第4章 项目进度管理之估算活动资源
- 图像清晰度计算的3种方法
- eclipse使用mapstruct_MapStruct使用学习
- 数据结构 C 代码:表达式求值
- Python分割视频
- oracle中jdk配置,Java Oracle JDK11在Windows上安装配置
- 计算机xp中丢失shell32,是怎么回事?电脑自动弹出记事本shell32?电脑自动弹出记事 爱问知识人...
- linux如何删除指定大小以下的文件夹,Linux中定时删除超过指定大小的文件夹