Simon Willison 5 月 4 日发了一个研究项目:用 Python 的 ctypes,对 Ville Laurikari 开发的 TRE 正则表达式引擎做了一层实验性 binding。
他做这件事的动机也很具体。TRE 最近因为 antirez 将其用于 Redis,被重新放回开发者视野。Willison 于是让 Claude Code 辅助生成了这个 Python binding,并用恶意正则样例测试它的 ReDoS 抵抗力。
结果并不复杂:在容易触发灾难性回溯的模式下,TRE 比 Python 标准库 re 更稳。原文还提到,TRE 可以处理“1000 万字符”级别的大输入,而 re 在某些较小输入上也可能被恶意模式拖垮。
但这不是一个“新库可以上线替换 re”的故事。
我更在意的是另一件事:Python 后端处理外部输入时,正则安全不能只靠开发者写得小心。引擎机制本身,也会决定最坏情况有多坏。
这次实验说明了什么:TRE 被拿来验证最坏情况
TRE 不是新引擎。它是 Ville Laurikari 的正则表达式引擎,特点之一是缺乏回溯机制。近期 Redis 引入 TRE,让这个老牌项目重新进入安全和基础设施开发者的讨论范围。
Willison 的 Python binding 更像一次探路。它用 ctypes 做封装,由 Claude Code 辅助生成,定位是研究和演示,不是成熟 Python 包。
这一点要说清楚。否则很容易把新闻读偏:看到“Python binding”,就以为已经有了生产级替代品;看到“比 re 稳”,就以为 TRE 全面优于 re。
目前能成立的判断窄得多:在 ReDoS 样例里,TRE 展示了更好的最坏情况表现。
对 Python 后端开发者来说,这个信号有用。尤其是服务里有搜索框、规则匹配、日志解析、Web 参数校验、用户自定义过滤条件时,正则并不是一段无害的小工具。它可能变成 CPU 黑洞。
关键差异不是平均速度,而是回溯会不会失控
ReDoS 的典型触发方式,是把不受控输入喂给有灾难性回溯风险的正则。攻击者不需要传很大的文件,也不一定需要高并发。某些模式下,一段精心构造的字符串就能让匹配过程陷入大量路径尝试。
这不是说 Python 的 re 全都不安全。风险集中在特定写法上,比如嵌套量词、歧义分支,再叠加外部输入。
TRE 的优势来自取舍。它不支持回溯,因此避开了许多指数级退化路径。代价也在这里:非回溯引擎通常不能保证兼容回溯引擎的全部语法和语义。
简单对比一下:
| 对比项 | Python 标准库 re | TRE |
|---|---|---|
| 当前位置 | Python 内置,生态默认选择 | C 正则引擎,Python binding 仍是实验封装 |
| 匹配机制 | 回溯式匹配 | 缺乏回溯机制 |
| ReDoS 风险 | 特定恶意模式下可能指数级退化 | 更接近线性扩展,最坏情况更可控 |
| 语法兼容 | Python 开发者熟悉 | 不能假设支持 re 全部语法 |
| 适合场景 | 普通业务正则、内部可控输入 | 高风险外部输入入口的安全评估对象 |
这也是为什么我不太买账“直接替换”的说法。
正则引擎不是只比快慢。它还比语法、语义、错误处理、平台支持、维护成本。更稳的最坏情况很重要,但不等于迁移成本为零。
类似路线并不陌生。Google 的 RE2 也以避免回溯、控制最坏情况性能著称,常被用于降低 ReDoS 风险。TRE 这次被带进 Python 试验场,说明同一类思路仍有现实价值:宁可少一点语法魔法,也要让匹配时间别失控。
Python 团队该怎么做:先审计入口,不要急着迁移
最该行动的不是所有 Python 用户,而是两类人。
一类是 Python 后端开发者。需要检查哪些接口会把用户输入带进正则匹配。比如搜索参数、上传文件名、日志查询条件、规则配置、Webhook 字段过滤。
另一类是应用安全工程师。需要把“正则最坏情况”纳入风险模型,而不是只看 SQL 注入、XSS、鉴权漏洞。
更现实的动作可以分三步:
- 盘点外部输入会触发的正则,标出高频接口和可被用户控制的模式。
- 给高风险匹配加超时、长度限制、隔离执行或 fuzz 测试。
- 对少量关键入口评估 TRE、RE2 这类非回溯引擎,而不是全库替换
re。
采购或平台团队也可以据此调整节奏。不要因为一个实验 binding 就把 TRE 写进生产方案。更合适的动作,是延后“立即替换”的决策,把它列入安全验证清单。
这里的现实约束不小。
ctypes 封装意味着跨平台打包、内存边界、错误处理、API 设计都要重新检查。TRE 和 Python re 的语法差异也需要系统梳理。没有这些工作,迁移只会把 ReDoS 风险换成兼容性风险。
接下来该看三件事,不看热闹指标。
第一,是否出现更严谨的 Python API,而不是只停留在研究脚本。第二,是否有人整理 TRE 与 Python re 的语法和语义差异。第三,是否有生产项目把它用于有限、可审计的正则入口,并说明边界。
如果这三件事没有进展,TRE Python binding 仍然只是一个有启发的安全演示。它能提醒团队重新审视正则入口,但还不能替团队承担上线责任。
文章开头的问题可以收回来:TRE 能不能补上 re 的 ReDoS 短板?
在特定恶意模式下,它至少给出了方向。可在 Python 生产环境里,真正的答案不在“换一个库”,而在“把最坏情况管起来”。
