为什么不推荐使用JS正则表达式?
为什么不推荐使用JS正则表达式?
RhoPaperWhy?
在JavaScript开发中,正则表达式(Regular Expressions,简称RegEx)是一种强大的文本处理工具,它能够识别字符串中的模式。然而,尽管正则表达式功能强大,但在某些情况下,我们并不推荐使用它。本文将探讨在JavaScript中使用正则表达式可能带来的危害,并列举历史事件来佐证这一观点。
正则表达式的复杂性
正则表达式的语法复杂,对于初学者来说难以理解和掌握。它们通常被称为“写给编译器的代码”,因为一旦编写完成,即使是原作者也很难读懂。这种复杂性会导致代码的可维护性降低,增加了开发和维护的成本。
性能问题
正则表达式的性能问题是一个不容忽视的因素。在某些情况下,正则表达式可能会导致灾难性的回溯(catastrophic backtracking),这会极大地影响程序的性能。例如,表达式/^([0-9]+)*$/
在处理某些字符串时,会尝试所有可能的匹配组合,导致性能大幅下降。在处理大型数据集时,这种性能问题尤为明显。
安全隐患
正则表达式可能引入安全隐患,尤其是在用户输入未经充分验证的情况下。复杂的正则表达式可能包含潜在的拒绝服务攻击(DoS)向量,攻击者可以构造特定的输入,使正则表达式的处理变得异常缓慢,从而消耗服务器资源。
历史上的倒霉蛋们
1. ReDoS攻击
在2016年,一个名为ReDoS(Regular Expression Denial of Service)的攻击被广泛报道。这种攻击利用了正则表达式中的回溯问题,通过构造特定的输入字符串,使得正则表达式的匹配过程变得异常缓慢,从而实现对服务的拒绝。
2. npm事件
2018年,npm(Node Package Manager)遭遇了一个安全事件,其中一个流行的正则表达式库中的一个正则表达式导致了性能问题。这个问题最终导致npm服务的延迟,影响了成千上万的开发者。
3. JavaScript引擎性能问题
在JavaScript的历史上,正则表达式引擎的性能问题一直是一个挑战。例如,某些复杂的正则表达式模式会导致V8引擎(Chrome和Node.js使用)的性能下降,这在处理大型文档或数据时尤为明显。
4. Cloudflare停机事件
Cloudflare在2022年6月21日遭遇了一次重大的服务中断,起因是正则表达式中的灾难性回溯问题。Cloudflare的WAF(Web Application Firewall)中的正则表达式.*.*=.*
导致了严重的性能问题,使得19个数据中心迅速宕机,影响了50%的总请求。
5. PHP(PCRE)性能比较
在不同语言自带的正则性能比较中,PHP(PCRE)在处理正则表达式为 .*.*=.*;
,测试文本为 a=bb…bb
(100 个 b)时,耗时 0.7ms-1ms,显示出性能上的问题。
6. Python性能问题
在同样的性能比较中,Python在处理相同的正则表达式和测试文本时,耗时 0.7ms-0.8ms,也显示出性能问题。
7. Golang性能问题
在性能比较中,Golang在处理相同的正则表达式和测试文本时,耗时大于 165ms,显示出性能问题。
8. Java性能问题
在性能比较中,Java在处理相同的正则表达式和测试文本时,耗时大于 5ms,显示出性能问题。
9. Chrome Console性能问题
JavaScript在Chrome Console中使用表达式 X(.+)+X
的测试耗时超过 20s,而在Regex的测试中耗时约为 200ms,可能是对JavaScript的实现不同导致的。
10. URI正则表达式问题
在Go中,使用URI正则表达式[\w]+://[^/\s?#]+[^\s?#]+(?:\?[^\s#]*)?(?:#[^\s]*)?
进行测试时,发现不同的正则表达式解决方案对编译的正则表达式的大小有限制,这可能导致性能问题。
11. Cloudflare 7.17事件
2019年7月17日,Cloudflare由于路由器错误配置导致全球性互联网访问中断,持续了27分钟,流量下降了50%。这次事件中,正则表达式的错误配置被认为是导致服务中断的原因之一。
吃瓜:Cloudflare多次因为正则表达式吃亏,Cloudflare的内部人员对于正则表达式的态度十分复杂,他们表现出些许对于正则表达式的厌恶,但是他们不得不使用正则表达式提供服务……
同情TA们3秒钟……下面是一些Cloudflare内部人员的言论,他们对正则表达式真的是有点厌恶。:
- 对事故的羞愧和对客户影响的道歉 :
Cloudflare的CEO Matthew Prince在事故发生后表示,他们对这次全球性的服务中断感到非常羞愧,并对给客户带来的影响表示道歉。他说:“我们知道这对我们的客户造成了多大的伤害。对此我们感到羞愧。”- 对正则表达式的看法 :
在事故发生后,Cloudflare的团队成员表示,他们将重新引入被删除的WAF CPU保护模块,并手动检查现有的所有规则,以查找可能存在的过度回溯问题。他们还计划切换到使用re2或者Rust的正则表达式引擎,这些引擎都具有运行时保证,以避免未来的问题。- 对事故的反思 :
一名Cloudflare的员工在博客中提到,这次事故是一个令人不安的服务中断,他们迅速做出反应以纠正这种情况,并正在纠正导致服务中断发生的流程缺陷。他说:“这对我们的客户和团队来说是一个很不安的事故。我们尽可能快的做出反应,并正在纠正我们流程中的缺陷。”- 对未来的承诺 :
Cloudflare的团队成员表示,他们相信通过更换所使用的基础技术,可以更深入地防止未来在进一步可使用正则表达式的方式能出现的问题。他们承诺:“我们相信这种全球性的宕机不会再发生了。”- 对正则表达式性能问题的分析 :
在另一篇分析文章中,Cloudflare的团队成员提到,他们将避免使用性能较差的正则引擎以及有问题的正则表达式,以防止灾难性的回溯问题。他们认识到,平时写正则的时候尽可能少用模糊匹配可以有效缓解回溯问题。
(以上内容来源于网络)
替代方案
鉴于正则表达式的上述问题,开发者开始寻找替代方案。例如,Cucumber Expressions提供了一种更直观、易于理解的文本匹配方式,它简化了表达式的编写,并增强了可读性和可维护性。此外,一些新的库和框架,如go-re2、regexp2等,提供了正则表达式的替代方案,它们在性能和内存消耗方面表现出色。
结论
正则表达式虽然功能强大,但在使用时需要谨慎。它们的复杂性、性能问题和安全隐患使得在某些情况下不推荐使用。开发者应该根据具体情况选择最合适的工具,或者寻找正则表达式的替代方案,以确保代码的安全性、可维护性和性能。