您的位置: 新闻资讯 > 行业动态 > 正文

从0到1:Redos攻击防护指南,你必须知道这些!(图文)


来源:mozhe 2025-04-22

一、什么是 Redos 攻击

{"type":"load_by_key","key":"auto_image_0_0","image_type":"search"}

Redos,即正则表达式拒绝服务攻击(Regular Expression Denial of Service) ,是一种利用正则表达式引擎特性来发起的拒绝服务攻击。正则表达式在编程中是一种强大的工具,用于匹配、查找和替换文本模式。比如,在验证邮箱格式时,我们会使用正则表达式来判断用户输入的字符串是否符合邮箱的基本格式规则。
正常情况下,正则表达式能够高效地处理各种文本匹配任务。然而,Redos 攻击的原理就在于攻击者精心构造特殊的输入字符串,利用某些正则表达式模式中存在的低效匹配逻辑,使得正则表达式引擎在匹配这些输入时,需要进行大量的回溯操作。回溯是指正则表达式引擎在匹配过程中,当尝试一种匹配路径失败后,返回上一个成功匹配的位置,尝试其他可能的匹配路径的过程。
举个简单的例子,假设我们有一个正则表达式^(a+)+$,它的本意是匹配由一个或多个a组成的字符串。当使用这个正则表达式去匹配aaaaaaaaaaaaaaa时,引擎可以很快完成匹配。但如果攻击者输入aaaaaaaaaaaaaaaX,对于这个不符合预期格式的输入,正则表达式引擎在匹配过程中,由于(a+)+这种嵌套量词的结构,会不断进行回溯尝试各种可能的a的组合,导致匹配时间呈指数级增长,消耗大量的 CPU 资源和时间 。
Redos 攻击的危害不容小觑。对于 Web 应用来说,可能导致应用响应缓慢甚至完全无法响应,使正常用户无法访问服务;对于服务器而言,大量的资源被消耗在处理这些恶意请求上,可能导致服务器崩溃,影响整个业务的正常运行。而且,由于正则表达式在各种编程语言和系统中广泛应用,无论是后端的服务器代码,还是前端的 JavaScript 验证,甚至是数据库查询、配置文件解析等场景,都有可能受到 Redos 攻击的威胁 。

二、Redos 攻击原理剖析


要深入理解 Redos 攻击,就必须先了解正则表达式引擎的工作机制。主流的正则表达式引擎实现方式主要有两种:确定有限状态自动机(DFA)和非确定有限状态自动机(NFA) 。DFA 引擎在匹配时速度较快,它从输入字符串的开头开始,根据正则表达式构建一个状态转移表,每一个字符的匹配都有明确的状态转移路径,不会产生回溯,所以对于普通的正则表达式匹配任务,DFA 引擎效率很高 。然而,DFA 引擎的功能相对有限,对于一些复杂的正则表达式特性,如捕获组、零宽断言等支持不够好 。
NFA 引擎则更为灵活,能够支持丰富的正则表达式特性,这使得它在实际应用中被广泛使用。但 NFA 引擎是表达式主导的,它从正则表达式的左边开始,每次读取一个字符,检查当前文本是否匹配当前表达式,如果匹配则继续处理下一个字符。当遇到分支(|)或者量词(*、+、? 、{n,m})时,NFA 引擎会记录多个可能的匹配路径 。一旦匹配失败,就会回溯到之前记录的位置,尝试其他可能的匹配路径。正是这种回溯机制,为 Redos 攻击提供了可乘之机。
以一个简单的正则表达式^(a+|b+)+$为例,它的含义是匹配由一个或多个a或者一个或多个b组成的字符串。当使用这个正则表达式去匹配字符串aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!时,由于字符串的末尾!不匹配正则表达式的任何部分,NFA 引擎会进行大量的回溯操作。它会不断尝试将前面的a分组为不同的组合,例如先尝试将所有的a都看作是a+的一次匹配,然后发现末尾不匹配,就回溯,将前面的a分成多个a+的组合,再尝试匹配,如此反复。随着输入字符串长度的增加,这种回溯操作的次数会呈指数级增长 。
假设输入字符串长度为n,对于上述正则表达式,可能的回溯次数大致可以用数学公式来估算。在最坏情况下,回溯次数可能达到2^n级别 。这意味着当输入字符串长度增加时,匹配所需的时间和计算资源会急剧上升,最终导致系统资源耗尽,无法正常响应其他请求,从而实现了拒绝服务攻击的效果。
再看一个更复杂的例子,正则表达式^((a+)+|(b+)+)+$,这个表达式中存在嵌套的量词结构。当匹配一个包含大量a或b的字符串时,回溯的情况会更加严重。因为不仅要考虑外层的(a+)+和(b+)+的组合,还要考虑内层a+和b+的不同组合方式,使得回溯的可能性大大增加,计算量呈指数级爆炸式增长 。
在实际的应用场景中,很多 Web 应用会使用正则表达式来验证用户输入,如验证用户名是否符合规则、邮箱格式是否正确等。如果这些正则表达式存在容易引发回溯的结构,攻击者就可以通过精心构造恶意输入,触发 Redos 攻击,使应用程序的服务器资源被大量消耗,导致正常用户的请求无法得到及时处理,影响业务的正常运行 。

三、常见的 Redos 攻击场景

(一)Web 应用中的 Redos 攻击


在 Web 开发中,正则表达式常用于验证用户输入,这也为 Redos 攻击创造了机会。许多 Web 应用会使用正则表达式来验证邮箱格式、用户名、密码强度等。以邮箱验证为例,常见的正则表达式如/^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$/,看似能有效验证邮箱格式,但如果攻击者构造一个超长的输入字符串,如a@a.a后面添加大量的字符,并且巧妙地利用正则表达式中的回溯点,就可能触发 Redos 攻击。
在一个实际案例中,某知名电商网站在用户注册时使用正则表达式验证用户名。攻击者通过编写脚本,向注册接口发送大量精心构造的恶意用户名,这些用户名包含了重复的字符和特殊的模式,使得服务器在验证时,正则表达式引擎陷入了长时间的回溯计算。由于服务器资源有限,大量的资源被消耗在处理这些恶意请求上,导致正常用户的注册、登录等操作无法及时响应,网站出现了卡顿甚至部分功能无法使用的情况,严重影响了用户体验和业务正常运转 。

(二)命令行工具中的 Redos 攻击


一些命令行工具也依赖正则表达式进行文本处理和参数匹配。例如,grep命令是 Linux 系统中常用的文本搜索工具,它支持使用正则表达式进行搜索。如果在使用grep时,用户不小心使用了容易引发 Redos 攻击的正则表达式,而又将其应用于处理大量文本,就可能导致命令行工具响应缓慢甚至系统卡顿。
曾经有一个系统管理员,为了在一个大型日志文件中查找特定的错误信息,使用了一个复杂的正则表达式grep -E '^.*(error1|error2|error3).*$' large_log_file.log。这个正则表达式中的.*和分支结构(error1|error2|error3)组合在一起,当日志文件非常大时,攻击者如果在日志中插入精心构造的恶意字符串,就可能使grep命令在处理该日志文件时陷入长时间的计算,消耗大量的 CPU 资源,影响服务器的正常运行 。

(三)数据库中的 Redos 攻击


在数据库中,正则表达式也常用于查询和数据验证。以 MySQL 数据库为例,它提供了REGEXP操作符用于正则表达式匹配。假设数据库中有一个用户表,包含用户信息,当执行查询语句SELECT * FROM users WHERE username REGEXP '^[a-zA-Z]+[0-9]{3,}$';时,如果攻击者能够控制查询条件中的输入,构造出类似于aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa这样的超长字符串,就可能导致数据库在执行正则表达式匹配时消耗大量资源,进而影响整个数据库系统的性能。
在某小型企业的内部管理系统中,使用 MySQL 数据库存储员工信息。攻击者通过 SQL 注入的方式,在查询员工信息的接口中插入恶意的正则表达式匹配条件,使得数据库在处理查询时,正则表达式引擎不断进行回溯计算,最终导致数据库连接池被占满,其他正常的数据库查询无法执行,整个管理系统陷入瘫痪,企业的日常运营受到严重影响 。

四、Redos 攻击的检测方法

(一)日志分析


服务器日志是检测 Redos 攻击的重要依据。通过分析服务器日志,可以发现异常的请求和响应时间。当服务器遭受 Redos 攻击时,日志中可能会出现大量来自同一 IP 地址的请求,并且这些请求的响应时间会明显变长 。
以 Web 服务器为例,在 Nginx 服务器的日志文件中,每一条日志记录通常包含了客户端 IP、请求时间、请求方法、请求 URL、响应状态码、响应时间等信息。假设正常情况下,一个请求的响应时间在几十毫秒到几百毫秒之间,如果发现某一个 IP 地址的请求,其响应时间突然飙升到数秒甚至数十秒,并且在短时间内有大量这样的请求记录,就有可能是遭受了 Redos 攻击 。
比如,通过以下命令查看 Nginx 日志文件:cat /var/log/nginx/access.log,在日志中发现类似如下的记录:

 
192.168.1.100 - - [2024-10-15 10:10:10] "POST /register HTTP/1.1" 200 1024 "-" "Mozilla/5.0" 5000
192.168.1.100 - - [2024-10-15 10:10:11] "POST /register HTTP/1.1" 200 1024 "-" "Mozilla/5.0" 4500
192.168.1.100 - - [2024-10-15 10:10:12] "POST /register HTTP/1.1" 200 1024 "-" "Mozilla/5.0" 5200
可以看到,来自 IP 地址 192.168.1.100 的请求,其响应时间(最后一个字段,单位为毫秒)都在 4500 毫秒以上,远超出正常范围,这就需要进一步检查该 IP 地址的请求是否包含恶意构造的输入,以判断是否遭受了 Redos 攻击 。
此外,还可以通过分析日志中的请求参数,查看是否存在异常的超长字符串或者特殊的字符组合。如果发现某个请求的参数中包含大量重复的字符,或者是与常见的 Redos 攻击模式相匹配的字符串,如大量的a、b等字符的重复,就需要警惕可能的 Redos 攻击 。

(二)工具检测

  1. 正则表达式检测工具:一些专门的正则表达式检测工具可以帮助发现代码中存在风险的正则表达式。例如,re2c是一个基于正则表达式的代码生成工具,它可以将正则表达式转换为 C 语言代码,并且在转换过程中会对正则表达式进行分析,检测是否存在容易引发 Redos 攻击的结构。使用re2c时,只需要将正则表达式按照其特定的语法格式编写在输入文件中,然后运行re2c命令,它就会输出对应的 C 语言代码,同时在输出中会提示正则表达式是否存在风险 。
  1. Web 应用防火墙:Web 应用防火墙(WAF)也是检测 Redos 攻击的重要手段。像 ModSecurity 是一款开源的 Web 应用防火墙,它可以集成到 Apache、Nginx 等 Web 服务器中。ModSecurity 通过规则集来检测和拦截恶意请求,对于 Redos 攻击,它可以通过配置规则,检测请求中的参数是否包含可能触发 Redos 攻击的正则表达式模式。例如,可以配置规则,当请求参数中出现连续重复的字符超过一定次数,或者出现特定的容易引发回溯的正则表达式结构时,就将该请求判定为恶意请求并进行拦截 。其配置文件中可能会有类似如下的规则:

 
SecRule ARGS "@rx ^(a+)+$" "id:1001,phase:2,t:none,block,msg:'Possible ReDoS attack detected'"
这条规则表示,当请求参数(ARGS)中匹配正则表达式^(a+)+$时,就触发规则,规则 ID 为 1001,在请求处理的 phase:2 阶段进行检测,采用 t:none 处理方式,对该请求进行拦截(block),并记录日志信息 “Possible ReDoS attack detected” 。
  1. 入侵检测系统(IDS)/ 入侵防御系统(IPS):IDS 和 IPS 也能够检测 Redos 攻击。以 Snort 为例,它是一款轻量级的入侵检测系统,通过分析网络流量,匹配特征库中的攻击特征来检测攻击行为。对于 Redos 攻击,Snort 可以通过更新特征库,添加针对 Redos 攻击的特征规则。当网络流量中出现与这些规则匹配的数据包时,Snort 就会发出警报 。其规则文件中可能会有类似如下的规则:

 
alert tcp any any -> $HOME_NET any (msg:"ReDoS attack detected"; content:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; nocase; sid:10001; rev:1;)
这条规则表示,当检测到 TCP 协议的数据包,源地址为任意地址,目的地址为本机网络($HOME_NET),并且数据包内容中包含 “aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa”(不区分大小写)时,就触发警报,警报信息为 “ReDoS attack detected”,规则 ID 为 10001,版本号为 1 。IPS 则在检测到攻击时,不仅会发出警报,还会主动采取措施,如阻断连接,以防止攻击进一步发生 。

五、Redos 攻击的防护手段

(一)编写安全的正则表达式

  1. 简化表达式结构:尽量避免使用复杂的嵌套量词和分支结构。例如,将^(a+)+$这种容易引发回溯的表达式,改为更简单直接的^a+$ 。后者只有一个量词,不会产生嵌套量词导致的指数级回溯问题。
  1. 使用非贪婪模式:在正则表达式中,贪婪模式会尽可能多地匹配字符,容易引发不必要的回溯。而非贪婪模式则会在满足条件的情况下,尽可能少地匹配字符。比如,对于匹配<.*>这种 HTML 标签的表达式,如果使用贪婪模式/<.*>/,当遇到<div>content1</div><div>content2</div>这样的字符串时,它会匹配整个字符串,因为它会尽可能多地匹配字符。而使用非贪婪模式/<.*?>/,则会分别匹配<div>和</div>,减少了回溯的可能性,提高了匹配效率和安全性 。
  1. 限制重复次数:明确限定重复字符或字符组的次数范围,避免出现无限制的重复。例如,使用{1,10}来限制某个字符或字符组重复出现的次数在 1 到 10 次之间,而不是使用*或+这种无限制的量词 。这样可以有效控制正则表达式在匹配时的计算量,防止因输入过长的字符串而导致资源耗尽。

(二)输入验证和过滤

  1. 长度限制:在接收用户输入时,对输入字符串的长度进行严格限制。比如,在验证邮箱格式时,除了使用正则表达式验证格式外,还可以限制输入字符串的长度在合理范围内,如不超过 254 个字符(这是 RFC 规定的邮箱地址的最大长度) 。可以在代码中使用简单的条件判断,如在 Python 中:

 
input_str = "user_input_email"
if len(input_str) > 254:
raise ValueError("输入的邮箱长度超过限制")
  1. 白名单过滤:只允许符合特定规则的字符输入,使用白名单机制过滤掉其他非法字符。以用户名验证为例,假设用户名只允许包含字母、数字和下划线,可以使用如下 Python 代码进行过滤:

 
import re
input_str = "user_input_username"
if not re.fullmatch(r'[a-zA-Z0-9_]+', input_str):
raise ValueError("用户名只能包含字母、数字和下划线")
  1. 结合多种验证方式:不要仅仅依赖正则表达式进行输入验证,可以结合其他验证方式,如使用字符串分割、字符匹配等简单方法进行初步验证。比如,在验证 IP 地址时,可以先使用字符串分割方法将输入字符串按.分割成四个部分,然后分别验证每个部分是否是 0 到 255 之间的数字,最后再使用正则表达式进行精确验证,这样可以减少因正则表达式漏洞而导致的攻击风险 。

(三)设置超时机制

  1. 在代码中实现超时逻辑:不同的编程语言有不同的实现方式。在 Python 中,可以使用signal模块来设置超时。例如,对于一个使用正则表达式匹配的函数:

 
import signal
class TimeoutException(Exception):
pass
def timeout_handler(signum, frame):
raise TimeoutException
def regex_match_with_timeout(pattern, string, timeout=5):
signal.signal(signal.SIGALRM, timeout_handler)
signal.alarm(timeout)
try:
import re
return re.search(pattern, string)
except TimeoutException:
print("正则表达式匹配超时")
finally:
signal.alarm(0)
pattern = r'your_pattern'
string = 'your_string'
result = regex_match_with_timeout(pattern, string)
上述代码中,regex_match_with_timeout函数设置了 5 秒的超时时间,如果正则表达式匹配过程超过 5 秒,就会抛出TimeoutException异常 。
  1. 利用框架或库的超时设置:一些 Web 框架或数据库连接库本身提供了超时设置选项。例如,在使用 Django 框架进行 Web 开发时,可以在数据库连接配置中设置查询超时时间 。在settings.py文件中:

 
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'your_database_name',
'USER': 'your_username',
'PASSWORD': 'your_password',
'HOST': 'your_host',
'PORT': 'your_port',
'OPTIONS': {
'connect_timeout': 10, # 连接超时时间10秒
'read_timeout': 30, # 读取数据超时时间30秒
},
}
}
这样可以确保在执行数据库查询(可能包含正则表达式匹配)时,如果操作时间过长,会自动终止,避免资源被无限占用 。

(四)使用安全的库和框架

  1. 选择经过安全审计的库:在使用正则表达式相关的库时,优先选择那些经过安全审计、有良好口碑的库。例如,在 Python 中,re2库是re库的替代品,它具有更快的速度和更好的安全性,对一些常见的 Redos 攻击模式有更好的防护能力 。可以通过pip install re2进行安装,然后在代码中使用:

 
import re2 as re
pattern = r'your_pattern'
string = 'your_string'
match = re.search(pattern, string)
  1. 关注框架的安全更新:对于使用的 Web 框架或其他开发框架,要及时关注官方发布的安全更新,并及时进行升级。例如,Spring 框架在安全方面做得很好,会定期发布安全补丁来修复潜在的漏洞,包括与 Redos 攻击相关的风险。开发人员应该按照框架的版本更新指南,及时将应用程序升级到最新的安全版本 ,以确保应用程序的安全性。

六、案例分析:成功防御 Redos 攻击的经验分享

(一)案例一:某电商平台的 Redos 防御实践


某大型电商平台在业务发展过程中,面临着日益增长的用户请求和复杂的业务逻辑。在用户注册和登录模块,使用正则表达式对用户输入的邮箱、用户名和密码进行验证 。然而,随着业务量的增加,平台开始遭受 Redos 攻击,导致服务器响应缓慢,用户体验受到严重影响 。
为了解决这一问题,平台技术团队首先对所有涉及正则表达式验证的代码进行了全面审查。他们发现,一些正则表达式存在复杂的嵌套量词和分支结构,容易引发 Redos 攻击。例如,在验证用户名的正则表达式中,使用了^([a-zA-Z0-9]+[._-]?)*[a-zA-Z0-9]+$这样复杂的表达式,其中([a-zA-Z0-9]+[._-]?)*这种嵌套结构在处理恶意输入时会导致大量回溯 。
技术团队决定对这些正则表达式进行简化和优化。他们将复杂的表达式拆分成多个简单的表达式,逐步进行验证。以用户名验证为例,先使用^[a-zA-Z0-9]+$验证用户名是否只包含字母和数字,然后再对特殊字符的使用进行单独验证,这样大大减少了回溯的可能性 。
同时,平台引入了输入验证和过滤机制。对所有用户输入的字符串长度进行严格限制,如邮箱地址长度限制在 254 个字符以内,用户名长度限制在 32 个字符以内 。并且采用白名单过滤,只允许合法字符输入,例如用户名只允许包含字母、数字、下划线和特定的符号 。
此外,平台还设置了超时机制。在处理用户请求时,如果正则表达式匹配时间超过 500 毫秒,就会自动终止匹配,并返回错误提示给用户 。通过这些措施的实施,该电商平台成功防御了 Redos 攻击,服务器响应时间恢复正常,用户体验得到了显著提升 。

(二)案例二:某金融机构的 Redos 防护策略


某金融机构的核心业务系统使用正则表达式进行数据验证和处理,涉及客户信息录入、交易数据校验等关键环节 。由于业务的敏感性和重要性,一旦遭受 Redos 攻击,可能会导致严重的经济损失和客户信息泄露 。
该金融机构采用了多种防护手段来应对 Redos 攻击。首先,在代码层面,他们选用了经过安全审计的正则表达式库,如在 Java 开发中,使用java.util.regex.Pattern类,并严格遵循安全的编程规范编写正则表达式 。例如,在验证银行卡号时,使用^[0-9]{16,19}$这样简洁明了的正则表达式,避免了复杂的结构 。
其次,金融机构利用 Web 应用防火墙(WAF)对所有的网络请求进行实时监控和过滤。他们配置了专门的规则来检测 Redos 攻击,当 WAF 检测到请求中包含可能引发 Redos 攻击的恶意输入时,会立即进行拦截,并记录相关日志 。同时,结合入侵检测系统(IDS)和入侵防御系统(IPS),对网络流量进行深度分析,及时发现并阻断潜在的 Redos 攻击行为 。
此外,金融机构还定期对系统进行安全漏洞扫描和渗透测试,模拟 Redos 攻击场景,检测系统的防护能力。通过不断地优化和改进防护策略,该金融机构成功抵御了多次 Redos 攻击尝试,保障了核心业务系统的稳定运行和客户数据的安全 。

七、总结与展望


Redos 攻击作为网络安全领域中一种隐蔽且具有破坏力的攻击方式,对各类应用系统的稳定性和可用性构成了严重威胁。通过深入了解 Redos 攻击的原理、常见场景以及检测和防护手段,我们能够更好地应对这一安全挑战 。
从防护要点来看,编写安全的正则表达式是第一道防线,简化表达式结构、使用非贪婪模式和限制重复次数等方法,能够有效减少因正则表达式设计不当而引发的攻击风险 。输入验证和过滤同样关键,严格限制输入长度、采用白名单过滤以及结合多种验证方式,可以从源头上阻止恶意输入进入系统 。设置超时机制能够在攻击发生时,及时终止可能导致资源耗尽的操作,避免系统长时间无响应 。而使用经过安全审计的库和框架,则为系统提供了更可靠的基础保障 。
展望未来,随着网络技术的不断发展,应用场景日益复杂,Redos 攻击也可能会呈现出新的变化和特点。一方面,人工智能和机器学习技术在网络安全领域的应用将不断深入,有望为 Redos 攻击的检测和防护带来新的思路和方法 。例如,利用机器学习算法对大量的网络流量和请求数据进行分析,能够更准确地识别出潜在的 Redos 攻击行为,实现实时预警和自动防御 。另一方面,随着云计算、边缘计算等新兴技术的普及,网络安全边界不断扩展,这对 Redos 攻击的防护提出了更高的要求 。需要进一步完善跨平台、跨系统的安全防护体系,确保在不同的计算环境下都能有效地抵御 Redos 攻击 。
此外,网络安全是一个动态的过程,随着攻击者技术的不断进步,我们的防护策略也需要持续更新和优化。未来,网络安全行业需要加强协作与交流,共同研究和应对 Redos 攻击等各类安全威胁,分享最新的安全技术和防护经验,推动整个行业的发展 。同时,企业和开发者也应提高安全意识,将安全融入到应用开发和系统运维的全过程,不断提升自身的安全防护能力,以适应不断变化的网络安全环境 。

关于墨者安全
墨者安全致力于安全防护、服务器高防、网络高防、ddos防护、cc防护、dns防护、防劫持、高防服务器、高防dns、网站防护等方面的服务,全网第一款指纹识别技术防火墙,自研的WAF指纹识别架构,提供任意CC和DDoS攻击防御。

热门文章

X

7x24 小时

免费技术支持

15625276999


-->