安全安装

默认情况下,pip 不会执行任何检查来防止远程篡改,并且涉及运行来自发行版的任意代码。然而,可以使用 pip 以改变这些行为的方式,以提供更安全的安装机制。

这可以通过以下操作来实现:

哈希检查模式

在版本 8.0 中添加。

此模式使用嵌入在 requirements.txt 文件中的本地哈希,以防止远程篡改和网络问题。这些哈希是使用 --hash 每个需求选项 指定的。

请注意,哈希检查是一个非此即彼的命题。对 *任何* 需求指定 --hash 将在全局范围内激活此模式。

要为包添加哈希,请将其添加到行中,如下所示:

FooProject == 1.2 \
  --hash=sha256:2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824 \
  --hash=sha256:486ea46224d1bb4fb680f34f7c9ad96a8f24ec88be73ea8e5a6c65260e9cb8a7

其他限制

  • *所有* 需求都需要哈希。

    这是因为部分哈希的 requirements 文件几乎没有用处,因此可能是错误:恶意行为者可以通过未哈希的其中一个需求将恶意代码偷偷地插入到安装中。

    请注意,通过 #md5=... 语法嵌入在 URL 样式需求中的哈希足以满足此规则(无论哈希强度如何,出于向后兼容性原因),尽管你应尽可能使用更强的哈希,如 sha256。

  • *所有* 依赖项都需要哈希。

    如果有一个依赖项没有在 requirements 文件中明确说明和哈希,则会导致错误。

  • 需求必须固定(要么到 URL、文件系统路径,要么使用 ==)。

    这将防止在发布与需求规范匹配的新版本时出现意外的哈希不匹配。

强制哈希检查模式

可以通过传递 --require-hashes 命令行选项强制启用哈希检查模式。

这在部署脚本中很有用,可以确保 requirements 文件的作者提供了哈希。它也是引导哈希列表的便捷方式,因为它会显示它获取的包的哈希。它只获取每个包的首选归档文件,因此你可能仍然需要使用 pip hash 添加替代归档文件的哈希:例如,如果存在二进制发行版和源发行版。

哈希算法

目前推荐的哈希算法是 sha256,但允许使用更强的算法,包括所有由 hashlib 支持的算法。但是,较弱的算法,如 md5、sha1 和 sha224,已被排除,以避免产生虚假的安全感。

每个包的多个哈希

可以为每个包使用多个哈希。当包为各种平台提供二进制发行版或当允许二进制发行版和源发行版都很重要时,这很重要。

与缓存的交互

在版本 23.1 中更改: 哈希检查模式也使用 本地构建的 wheel 缓存

从哈希检查模式下的本地构建的 wheel 缓存中安装时,pip 会将哈希与用于构建 wheel 的原始源发行版的哈希进行验证。这些原始哈希是从存储在每个缓存条目中的 origin.json 文件中获取的。

使用来自 PyPI(或其他索引服务器)的哈希

PyPI(以及某些其他索引服务器)在每个下载 URL 的片段部分提供了发行版的哈希,例如 #sha256=123...,pip 会将其作为防止下载损坏的保护措施进行检查。

其他从 hashlib 获得保证支持的哈希算法也在这里受支持:sha1、sha224、sha384、sha256 和 sha512。由于此哈希来自远程,因此它不是防止篡改的有用保障,因此不能满足 --require-hashes 要求每个包都有本地哈希的要求。

可重复安装

哈希检查模式也适用于 pip downloadpip wheel。有关哈希检查模式与其他可重复性策略的比较,请参阅 可重复安装

警告

注意 setup.py 中的 setup_requires 关键字参数。使用它的(罕见的)包将导致 setuptools 直接下载这些依赖项,跳过 pip 的哈希检查。如果你需要使用这样的包,请参阅 控制 setup_requires

不要直接使用 setuptools

小心不要通过直接使用 setuptools 的已弃用接口来安装你的实际项目,从而使你所有的安全工作失效:例如,通过调用 python setup.py installpython setup.py developeasy_install

这些将乐于在你的 requirements 文件中未包含的任何内容,并且在你的项目发展过程中很容易错过东西。为了安全起见,使用 pip 和 --no-deps 安装你的项目。

而不是 python setup.py install,使用

$ python -m pip install --no-deps .
$ python -m pip install --no-deps .
C:> py -m pip install --no-deps .

而不是 python setup.py develop,使用

$ python -m pip install --no-deps -e .
$ python -m pip install --no-deps -e .
C:> py -m pip install --no-deps -e .