跳至内容

通过双重身份验证保护 PyPI 帐户

PyPI 做出的关键安全承诺之一是,当你下载某些内容时,只有与该项目相关的人员才能上传、删除或以其他方式修改项目。当你查看该项目并发现它归你信任的人员所有时,你可以确信没有其他人正在对 PyPI 上的该软件包进行更改。

这一承诺取决于 PyPI 上用于创建和维护 Python 项目的每个个人帐户的安全。在过去,我们采取了措施来保护这些帐户,例如 阻止被盗密码、使用 TOTPWebAuthN 提供强大的 2FA 支持、支持带有脱机衰减的 API 令牌将下载量最大的项目注册到强制性 2FA 以及 启用短时限令牌以进行上传

今天,作为长期保护 Python 生态系统努力的一部分,我们宣布,到 2023 年底,所有在 PyPI 上维护任何项目或组织的帐户都将被要求在其帐户上启用 2FA。

从现在到今年年底,PyPI 将开始根据 2FA 使用情况限制对某些网站功能的访问。此外,我们可能会开始选择某些用户或项目进行提前实施。

我该做些什么准备?

为准备工作,最重要的是尽快为您的帐户启用 2FA,可以使用 安全设备(首选)或 身份验证应用程序,以及切换到使用 受信任的发布者(首选)或 API 令牌 来上传到 PyPI。

为什么要使用 2FA?

帐户接管攻击通常源于有人使用不安全的密码:可能是密码很容易猜到,或者密码被重复使用并在泄露事件中出现。使用该不安全的密码,攻击者可以控制维护者的帐户,并开始采取行动,就像他们自己一样。

这在像 PyPI 这样的网站上尤其成问题,因为一个人可以采取的行动包括发布可能被全世界人民使用的软件,允许攻击者在不知情的用户的计算机上安装和执行软件。 帐户接管攻击之前已被用于以这种方式破坏 PyPI 用户

双重身份验证立即消除了与被盗密码相关的风险。如果攻击者拥有某人的密码,那就不足以让他们访问该帐户了。

为什么每个项目或组织维护者都需要?

有两种方法可以理解这个问题

  • 为什么每个项目和组织维护者都需要,而不是仅仅一小部分人(根据流行度、目的、用户是否使用他们的帐户等)?
  • 为什么只有维护者需要,而不是每个用户?

并非 PyPI 上的每个帐户对攻击者都有相同的价值。能够访问 PyPI 上下载量最大的项目的帐户可以用来攻击比能够访问下载量最小的项目的帐户多得多的人。

但是,如果某人依赖项集中的一个项目被破坏,就会破坏他们的计算机。攻击者并不在乎他们是从广泛使用的项目还是小众项目中得到你,只要他们得到了你。更糟糕的是,一旦被破坏,攻击者可以将攻击扩展到攻击其他系统,包括现在被破坏的人员维护的 PyPI 上的其他项目。

鉴于只需要一个被破坏的项目,无论下载量有多少 1,就会破坏某人,我们希望确保每个项目都受到 2FA 的保护。

另一方面,没有访问任何项目的帐户不能用来攻击任何人 2,因此它是一个非常低价值的目标。

我们认识到,为帐户启用 2FA 会对帐户所有者 PyPI 3 造成非零成本,因此强迫那些无法影响任何人(除了他们自己)的帐户这样做,并不是有效利用有限资源的做法。此外,从实际角度来看,大多数人所熟悉的以及 PyPI 实现的标准 2FA 流程也涉及将 2FA 令牌添加到现有帐户中,而不是强制它成为注册流程的一部分。

我们预计,对于目前不是项目维护者或组织成员的用户来说,最终的体验将是,当他们尝试执行需要添加 2FA 的操作(创建新项目、接受邀请、创建组织等)时,系统会提示他们在继续之前向其帐户添加 2FA。

为什么现在?

在过去 5-10 年中,许多项目在开源社区中或为开源社区提供服务的趋势是越来越关注供应链安全,防止通过“供应链”交付的攻击,即用于创建和使用软件的服务和工具。

2022 年 7 月,我们宣布了 安全密钥赠送活动,以及一项计划,即开始为 PyPI 上下载量排名前 1% 的项目强制实施 2FA。

最初宣布针对下载量排名前 1% 的项目实施该强制措施以及相关的赠送活动,引起了各种反应,从赞扬这种努力的人到决定不在 PyPI 以外的地方分发代码的人都有。我们计划将此限制在下载量排名前 1% 的项目中,因为这些项目可能是攻击者的最高价值目标,并且因为我们担心这种强制措施会对 PyPI 上项目的维护者以及 PyPI 团队本身的支持负担造成影响。

在去年这个时候,我们没有计划或预期扩大受该强制措施约束的用户范围,除非自然而然地出现项目人气上升的情况,成为下载量排名前 1% 的一部分。

然而,在过去一年中,一些事情发生了变化。

  • 我们对 2FA 的实施以及它对发布到 PyPI 的人和 PyPI 团队本身的影响更有信心了。
  • 我们发布了诸如 受信任的发布 之类的功能,这些功能有助于消除 2FA 对发布带来的某些负担(这是用户最常见的操作)。
  • GitHub 进一步推进了其 强制要求其平台上的所有贡献者使用 2FA 的计划,使得更多人已经(或很快就会)准备应对使用 2FA 的要求。
  • PSF 收到资金,雇佣了一名 PyPI 安全工程师。虽然这个职位不是专门处理支持请求的,但对整体安全态势以及实施细节的重点关注,将改善 PyPI 的整体状况,对用户和项目维护者都有益,并有助于减轻 PyPI 志愿者的一些压力。
  • 支持最终用户的工作量在很大程度上依赖于一小群志愿者。当我们的信任管理员看到用户帐户报告时,我们必须花时间进行适当的调查。这些报告通常被视为紧急情况,需要红色警报级别的紧急处理。通过对项目维护者强制实施 2FA,帐户接管的可能性会大大降低,从而为真正特殊的情况保留了紧急状态。帐户恢复成为正常例行支持工作的一部分,而不是管理级别的紧急情况。

所有这些因素共同促使我们得出结论,我们可以将我们的强制措施扩大到 PyPI 上所有项目维护者,同时最大程度地减少对项目维护者和 PyPI 管理员的影响,并以一种改善 PyPI 和更广泛的 Python 生态系统可持续性的方式进行。

供应链安全不是企业的责任吗?

有些人认为,改善供应链安全对企业或商业用户有利,而个人开发者不应该被要求为他们承担未经补偿的负担。

我们认为这是一种短视的行为。

供应链中的漏洞可以用来攻击个人开发者,就像它能够攻击企业和商业用户一样。事实上,我们认为个人开发者比企业和商业用户处于脆弱的境地。虽然企业通常能够雇用员工并投入资源来审查他们的依赖项,但个人开发者通常无法做到这一点,他们必须花费自己有限的空闲时间来做到这一点 4

让个人开发者更加糟糕的是,在发生漏洞的情况下,企业更有可能拥有专家来帮助他们检测和修复漏洞,而个人开发者则必须独自完成这一切。在极端情况下,企业通常有保险来弥补他们遭受的任何损失,而个人开发者几乎总是没有保险。

我们认识到供应链安全影响所有人,无论他们规模大小,我们致力于保护所有用户。


Donald Stufft 是 PyPI 管理员,自 2013 年起一直维护 Python 包索引。


  1. 从技术上讲,一个下载量为 0 的项目实际上与一个不存在的项目相同,但将不存在的项目与存在的项目区分开来比将 0 下载量与 1 下载量区分开来更容易。这在 PyPI 上尤其如此,因为大量的镜像和扫描仪意味着没有项目真正实现了 0 次下载量。 

  2. 除了帐户所有者自己,因为这会拒绝他们访问自己的帐户。 

  3. 对于最终用户,它迫使他们购买某种硬件令牌*或*使用某种TOTP应用程序。在这两种情况下,它都迫使他们除了密码之外还需要跟踪其他东西,并改变了他们习惯的登录流程。对于PyPI来说,它增加了某人可能被锁定在他们帐户之外的可能性,需要管理员干预。 

  4. 并非无缘无故,但PyPI也是一个开源项目,主要由志愿者运营,清理PyPI上的漏洞会严重影响这些志愿者。