python 的pip
包管理器是否在下载它们之后和安装它们之前以加密方式验证所有包的有效负载的身份验证和完整性?
我看到很多指南提供安装说明以及要求用户安装 python 依赖项的步骤pip install ...
。我通常不这样做,因为我相信我的操作系统包管理器(即apt
)在安装之前实际验证包的来源/信任和完整性。
pip
默认情况下,在安装之前是否为所有下载的项目提供加密身份验证和完整性检查?
注意:通过 X.509 的传输验证不算作有效的身份验证/完整性检查。
python 的pip
包管理器是否在下载它们之后和安装它们之前以加密方式验证所有包的有效负载的身份验证和完整性?
我看到很多指南提供安装说明以及要求用户安装 python 依赖项的步骤pip install ...
。我通常不这样做,因为我相信我的操作系统包管理器(即apt
)在安装之前实际验证包的来源/信任和完整性。
pip
默认情况下,在安装之前是否为所有下载的项目提供加密身份验证和完整性检查?
注意:通过 X.509 的传输验证不算作有效的身份验证/完整性检查。
有点...
首先,Pypi
包括正在下载的文件的哈希,以便发现服务器和客户端之间的任何修改/错误。
其次,pip
支持哈希检查模式,您可以在该模式下为请求的包指定所需的哈希,requirements.txt
格式如下:
Foo==1.2.3 --hash=sha256:xxxxxxx
pip
然后将验证下载的包是否散列到该值,如果不是则错误。https://pip.pypa.io/en/stable/reference/pip_install/#hash-checking-mode
第三,Pypi
具有可以将签名与包一起上传的机制。twine对此有支持。
然后,您可以在软件包旁边下载签名并进行验证。签名文件位于相同的 url,但.asc
附加了 - 例如https://pypi.python.org/packages/py2.py3/p/pip/pip-7.1.2-py2.py3-none-any.whl
,它的签名在https://pypi.python.org/packages/py2.py3/p/pip/pip-7.1.2-py2.py3-none-any.whl.asc
您可以通过下载两个文件并运行例如手动进行验证
gpg --verify mypackage.whl.asc mypackage.whl
但是,目前工具中没有内置机制pip
来代表您自动执行此步骤 - 尽管最近在开发人员中多次讨论这是一项急需的功能。
简短的回答是:pip 总是使用 TLS,这在这里实际上相当有用。这意味着只要没有人设法破坏 PyPI 本身或窃取站点证书,那么您就可以确定您下载的包是 PyPI 管理员认为正确的包。而且很难做得比这更好:毕竟,PyPI 管理员是唯一知道允许哪些用户上传哪些包的人,所以你必须信任他们。
正如 match 所提到的,过去还有一种方法可以为包上传 PGP 签名。然而,这已经被删除了,因为它基本上只是安全剧院——很复杂,让人感觉你很安全,但实际上并没有提高安全性。PyPI 的一位主要管理员有一篇关于此的旧帖子:https ://caremad.io/posts/2013/07/packaging-signing-not-holy-grail/
更好的是使用像TUF这样的框架,它可以提供这样的保证:“上传这个的人在上传时受到 PyPI 管理员的信任,如果 PyPI 之后被入侵,那么攻击者就不能回去了改变妥协之前发生的任何事情”。TUF 与 linux 发行版使用的包签名大致相似,但功能更强大一些。PyPI 维护者获得了实现这一点的资助,现在工作正在进行中:https ://wiki.python.org/psf/PackagingWG#Warehouse:_Facebook_gift
一个挑战是,要引导这样一个加密系统,你需要一个密钥签名仪式,这将在今年的 PyCon 上亲自举行......但是,好吧。请耐心等待:-)
同时,您可以通过将包哈希放入您requirements.txt
的 . 或者一些依赖管理工具,例如pipenv
或poetry
会自动为您执行此操作。
否。截至 2020 年,pip
它不会对从 PyPI 下载的任何包提供加密完整性或身份验证。
2013 年,PEP 458被提出作为解决此问题的解决方案。
2019 年,Python 软件基金会宣布 Facebook 捐赠资金来实施它。
截至 2020 年年中,这项工作仍在进行中,可以通过Python Packaging Authority的这个Github Milestone进行跟踪。
同时,您能做的最好的事情就是希望 python 模块的开发人员:
发布一个加密签名的文档,包括其发布的校验和,然后您可以将其pip
与--hash
参数一起传递