Hacker News 中文摘要

RSS订阅

当str.lower()成为Python中的安全漏洞 -- When str.lower() is a security vulnerability in Python

Python的str.lower()方法在处理国际化域名时存在安全漏洞,因为它仅支持ASCII字符,而IDNA 2003标准已被IDNA 2008取代,建议使用idna包而非Python内置的idna编码。

正文

根据英文文章内容,中文重新陈述如下:

标题:Python中str.lower()为何会成为安全漏洞

来源: Seth Larson 于2026年8月18日发布

核心内容:

一些互联网标准仅支持ASCII字符,但全球语言远不止拉丁字母。因此,需要将Unicode映射为ASCII以用于域名。NamePrep(RFC 3491)是解决方案的一部分,作为StringPrep(RFC 3454)的配置文件,是国际化域名应用(IDNA 2003)的关键组件。IDNA 2003已被IDNA 2008(RFC 5890等)取代。

Python通过idna编解码器支持IDNA 2003(str.encode('idna')),而IDNA 2008由PyPI上的idna包支持。Python的StringPrep实现位于标准库的stringprep模块中。通常应使用idna包(IDNA 2008),而非.encode("idna")(IDNA 2003),但有时仍需旧行为。

StringPrep在RFC 3454第3.2节定义了“大小写折叠”步骤,通过映射表B.2和B.3实现字符串的不区分大小写比较。B.2相当于str.lower(),按Unicode规则将所有字符小写;B.3包含例外。Python实现代码如下:

def map_table_b3(code): r = b3_exceptions.get(ord(code)) if r is not None: return r return code.lower()

然而,str.lower()存在漏洞!因为str使用Python解释器自带的Unicode数据(可通过unicodedata.unidata_version查看版本),而StringPrep依赖Unicode 3.2.0版本。Python提供了unicodedata.ucd_3_2_0数据库专门用于StringPrep和IDNA算法。调用str.lower()会导致实现与规范不一致,从而产生漏洞。例如,使用Unicode 17.0.0的大小写折叠规则与RFC 3454合规值不同。

修复方法是创建新的例外,使str.lower()在特定函数中模拟Unicode 3.2.0的行为。通过逐一检查每个Unicode码点,记录当前Python版本与Unicode 3.2.0之间str.lower()行为的差异。这样,IDNA 2003便与规范保持一致。

感谢Bitshift报告漏洞,Stan Ulbrych共同开发修复方案,以及Marc-Andre Lemburg和Petr Viktorin审查修复。详情见CVE-2026-17084。

(注:作者作为Python软件基金会安全驻留开发者,工作由Alpha-Omega赞助。)

评论

根据评论内容,主要围绕Python中str.lower()函数因Unicode版本差异引发的安全漏洞展开讨论,观点如下:

1. 漏洞性质争议 - 部分评论认为这是实现与规范不符的漏洞(评论1、7),而非单纯bug。评论7指出:"string.lower() is not a security vulnerability. Not following the spec is the security vulnerability." - 评论1质疑漏洞的可利用性:"Vulnerability for me sounds like there’s a reasonable way to create an exploit from the bug"

2. 具体技术问题 - 评论3强调TLS/SSL中SAN域名匹配规则:"The rule for how SAN DnsNames match... is literally byte comparison" - 评论5指出大小写转换的意外行为:"Python did ß.upper() returns 'SS'... if string length changes with an upper call" - 评论11批评修复方案:"sounds like a really hacky solution compared to implementing a separate frozen Unicode 3.2.0 lower"

3. 实际影响与案例 - 评论6引用Spotify安全事件:"Reminds me of an old security incident at Spotify" - 评论4建议检查IDN域名:"look for '.lower()' squatters if you host on an idn" - 评论13提及实际遭遇:"Hit this with the Kelvin sign once"

4. 其他观点 - 评论12调侃影响范围:"All 6 users of IDNs must be really worried right now" - 评论14建议改进错误提示:"If this is so important to know you probably shouldn't serve 403 errors to people"

总结:核心争议在于str.lower()因Unicode版本差异导致的规范偏离是否构成安全漏洞,以及修复方案的合理性。多数评论认可其潜在风险,但对其严重性存在分歧。