HeadlinesBriefing favicon HeadlinesBriefing.com

Python str.lower() IDNA 安全漏洞修复

Hacker News •
×

一些互联网标准仅支持ASCII字符,但世界范围内使用的字符远不止拉丁字母。因此,需要将Unicode映射到ASCII以用于域名。Name Prep是该解决方案的一部分,定义在RFC 3491中作为String Prep的一个配置文件,是Internationalizing Domain Names in Applications(IDNA)的关键组成部分,亦称为“IDNA 2003”。String Prep算法定义在RFC 3454中。IDNA 2003已被IDNA 2008(定义于RFC 5890、5891、5892和5893)取代。Python通过idna编解码器(str.encode('idna'))支持IDNA 2003,而IDNA 2008由Python包索引上的idna包支持。Python对String Prep的实现位于标准库的stringprep模块中。

一般情况下,您应该使用idna包(IDNA 2008),而不是.encode("idna")(IDNA 2003),但有时您确实需要旧版行为。String Prep在第3.2节定义了“大小写折叠”步骤(大小写折叠约等于“如何将代码点转换为小写/大写”),通过映射表B.2和B.3实现字符串的大小写不敏感比较。B.2实际上是str.lower(),按照Unicode规则将所有字符转换为小写,而B.3包含例外情况。

此函数中的str.lower()调用是一个漏洞!因为str使用特定Python解释器随附的Unicode数据,您可以通过访问unicodedata.unidata_version来确定特定Python解释器使用的Unicode版本。每个版本的Python中还有一个Unicode 3.2.0的数据库可用(unicodedata.ucd_3_2_0),专为String Prep和IDNA算法提供。String Prep依赖于该特定版本的Unicode才能一致地运行,RFC 3454中的B.2和B.3表本质上是编码为表格的Unicode 3.2.0大小写折叠规则。因此,我们需要使用Unicode 3.2.0的大小写折叠规则,而非更新的Unicode大小写折叠规则。

修复方法是创建新的例外,使得str.lower()在特定函数上行为如同使用Unicode 3.2.0。感谢Bitshift报告此漏洞,Stan Ulbrych参与开发补救措施,Marc-Andre LemburgPetr Viktorin审查了补救措施。详见CVE-2026-17084

关键实体:公司:Python软件基金会,Alpha-Omega | 人物:Seth Larson、Bitshift、Stan Ulbrych、Marc-Andre Lemburg、Petr Viktorin