正则表达式是一种功强大而灵活的文本处理工具。一般来说,正则表达式就是以某种文本的方式来表述字符串,一次你可以说:“如果一个字符串会有这些东西,那么它就是我们要找的东西”。再好的东西如果使用不当依然会造成灾难性后果。
一天晚上突然收到同事反馈,其使用的一个正责表达式对收货人姓名处理时,输入某种字符不能正确保存,现象为服务端请求卡死,没有response返回给客户端;在测试环境重现该问题时通过jstack获取到的信息可以发现正则表达式在回溯处理,进一步通过RegexBuddy对该段正则表达式分析发现该该段正则表达式处理完成需要超过一百万次匹配如果有恶意用户发现该漏洞,对网站发起ReDoS(Regular expression Denial of Service)
攻击(注:根据韩波同学意见修改),可能会引发灾难性的后果。
![](https://i-blog.csdnimg.cn/blog_migrate/b78b92deb17c4b813bebf9050cbb9c16.png)
![](https://i-blog.csdnimg.cn/blog_migrate/a646d37db7b6d6a560b7af0af983ee8a.png)
如果整个输入字符串仅包含数字字符,则这是一个相当简单的匹配正则表达式。^ 和 $ 字符分别表示字符串的开头和结尾,表达式 \d 表示数字字符,+ 指示将有一个或多个字符匹配。我们使用 123456X 作为输入字符串测试此表达式,那么最终又是什么情况呢?同样通过RegexBuddy分析一下,可以发现NFA总共计算出了6个路径:123456、12345、1234、123、12 和 1;经过了20步处理才发现是不符合要求的。下面通过介绍正则表达式的匹配模式去分析一下该如何处理。
正则表达式匹配模式
- 贪婪型
- 勉强型
- 占有型
![](https://i-blog.csdnimg.cn/blog_migrate/ce51f0ecabfe10db28a313494549a91f.png)
![](https://i-blog.csdnimg.cn/blog_migrate/04bfc03f8fe3a06a4c8a607c0e457081.png)