通用技术 性能测试与 “正则表达式”

JoyMao · 2022年05月26日 · 最后由 JoyMao 回复于 2022年06月02日 · 6361 次阅读

说明

翻看自己以前的性能测试报告,有一篇比较特别,是关于测试正则表达式的(2018 年),觉得比较特别,在这里分享一下。
(特别说明,我的正则水平不高,“指数型正则”、“嵌套型正则 “是根据现象给的叫法,勿较真)

邮箱格式校验

需求里有个要求:“@ 前后内容不能以点 (.) 开头,但可以数字、字母、下划线连接线 (_-) 开头”
而前端开发写的匹配 email 格式的正则及对应分析图:

分析:
(\.?(-|\w)+)*)[A-Za-z0-9]这个是明显的指数型正则特征
因为"\w+"是包含"[A-Za-z0-9]"的,如果其后跟的内容不匹配正则,将会不断的进行回溯。

用 a.aaaaaaaaaaaaaaa@a.x-x 测试一下就知道这个错误正则的可怕了 -- 已经溢出测试工具的上限了

浏览器页面上都不敢尝试,肯定卡死。
这里的测试语句虽然很短,但因为 x-x 无法匹配,前的匹配项过多,造成大量的回溯

补充:
有些看似指数,却不一定是:
比如(\w+=)+$ 、 (\w+=+)+$就可能不是(暂时码不准,没找到合适的测试语句),因为\w不包含=,且=前面\w必须大于1个
但(\w+a)+$是指数型,因为\w包含a,使用aaaaaaaaaaaaaaaaaaaaaaaaa=去测试就溢出了

sql 注入检查正则

没看错,当时为了防止 sql 注入,开发手写正则来拦截可能有 sql 语句的输入,而不是借助其他成熟的工具,但测还得测试。
开发的正则如下:

对应超长的正则分析图

分析:
from后面涵盖匹配项包含了where及其后续的内容,即where处即可认为是“数据库表名”又可匹配后面的where处内容。

那么使用如下的输入

1>((substr((select from A where 1= where 1= where 1= where 1= where 1= where 1= where 1= where 1= where 1= where 1= where 1= where 1= where 1= where 1= where 1= where 1= where 1= where 1= where 1= where 1=/),1,1))

当提供如上测试语句时,因为匹配内容不符合时,会不断回溯。嵌套的内容越多,回溯的步骤越多(这里到了 6255 步,当然没有指数型那么夸张)

这个语句虽然不能注入,但会极大的影响服务器的性能,造成 其他安全问题

tips: 正则可视化网站:https://regexper.com/

共收到 4 条回复 时间 点赞

这跟性能测试有关系?

Thirty-Thirty 回复

那你认为的性能测试是什么?用个工具压一压?
错误的代码(这里是正则),会造成服务器或浏览器异常
这种类似白盒性质测试,会提前发现性能问题

至于正则造成的性能故障,有很多现实实例,比如:
https://zhuanlan.zhihu.com/p/456349063

没有直接影响 I/O,算不上性能测试,顶多在测试正则的覆盖率

AlexYou 回复

性能只受 I/O 影响?你确定指数型正则解析不影响 I/O?
具体案例见二楼回复

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册