验证PyPI Python包的完整性

7

最近有一些关于一些恶意库上传到Python软件包索引(PyPI)的消息,具体信息请见以下链接:

  1. PyPI上的恶意库
  2. 官方Python仓库中发现的恶意模块 (此链接包含恶意软件包列表)
  3. 使用恶意Python模块的开发者

我并不是想转发这些新闻,而是想防止自己和其他团队成员识别出是否从PyPI下载的软件包已被外部人员篡改。

问题:

  1. 我从PyPI下载软件包后应该使用哪种安全检查?MD5签名还是其他额外步骤?
  2. MD5签名足以验证Python软件包的完整性吗?

Typosquatting与哈希无关。您必须验证是否使用了上游软件包。 - Tatsuyuki Ishi
另一个问题:一旦我下载了一个软件包并检查它没有任何typosquatting,MD5签名是否足以检查此软件包的完整性? - abautista
pip 应该验证 MD5 签名,而且它不容易(如果可能的话)发生碰撞。编辑:新的 PyPI 前端(pypi.io)已迁移到 SHA256。 - Tatsuyuki Ishi
但是 pip 不支持加密签名,因此这种方式不可行。 - abautista
另一个问题:一旦我下载了一个软件包并检查它没有任何typosquatting,MD5签名是否足以检查此软件包的完整性?不,MD5不是签名;它是哈希。而且它是一种不安全的哈希。 - Michael Altfield
2个回答

3
首先,本文描述了“typosquatting”的危险性,这是由于开发人员盲目按名称安装软件包而不检查其是否为正确的上游软件包所导致的。您可以通过访问作者的GitHub存储库并正确复制安装说明来避免此问题。
除此之外,软件包可能会被篡改,但这种情况不太可能发生。由于PyPI文件通过HTTPS传输,从服务器获取哈希值并进行验证并没有太大意义。(如果作者的账户或PyPI服务器被黑客攻击,则哈希值无法防止您安装恶意软件包。)
如果您需要额外的安全措施来防止服务器受到攻击,请使用固定版本/哈希值。有关详细信息,请参见文档

2
首先,您担心使用 pipPyPI 下载时获得恶意文件的担忧是合理的。实际上,截至2020年,pip无法以加密方式验证它下载的软件的真实性和完整性(但自2013年以来一直是待办事项)。
其次,md5 可以验证文件的完整性,但不能安全地这样做。仅检查完整性也不足以确保安全。要安全地验证从 pip 下载的文件是否是您期望的文件,您必须:
  1. 通过确认发布者(使用加密签名)确实生成了该文件来对文件进行身份验证;以及
  2. 在下载后验证文件的完整性
尽管 pip 没有内置支持,但您可以通过手动从 PyPI 下载所需的文件及其分离的签名文件,然后使用 gpg 检查签名来手动完成此操作。
例如,borgbackup 项目可以在 PyPI 网站上查看: 点击“下载文件”按钮,您可以选择在以下URL下载最新的tarball: 或者,您也可以使用cURL针对PyPI“simple”API获取此URL。
user@disp5066:~$ curl -s https://pypi.org/simple/borgbackup/ | grep -i borgbackup-1.1.13.tar.gz
    <a href="https://files.pythonhosted.org/packages/97/68/27d96a12f54894223ad6676ce4d215ad61771e3e723580f3ee6e609e17b7/borgbackup-1.1.13.tar.gz#sha256=164a8666a61071ce2fa6c60627c7646f12e3a8e74cd38f046be72f5ea91b3821">borgbackup-1.1.13.tar.gz</a><br/>
user@disp5066:~$ 

获取此文件的签名,只需在URL末尾添加.asc即可:
user@disp5066:~$ wget https://files.pythonhosted.org/packages/97/68/27d96a12f54894223ad6676ce4d215ad61771e3e723580f3ee6e609e17b7/borgbackup-1.1.13.tar.gz.asc
--2020-07-02 07:51:12--  https://files.pythonhosted.org/packages/97/68/27d96a12f54894223ad6676ce4d215ad61771e3e723580f3ee6e609e17b7/borgbackup-1.1.13.tar.gz.asc
Resolving files.pythonhosted.org (files.pythonhosted.org)... 151.101.37.63, 2a04:4e42:9::319
Connecting to files.pythonhosted.org (files.pythonhosted.org)|151.101.37.63|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 862 [application/octet-stream]
Saving to: ‘borgbackup-1.1.13.tar.gz.asc’

borgbackup-1.1.13.t 100%[===================>]     862  --.-KB/s    in 0s      

2020-07-02 07:51:14 (37.2 MB/s) - ‘borgbackup-1.1.13.tar.gz.asc’ saved [862/862]

user@disp5066:~$ cat borgbackup-1.1.13.tar.gz.asc 
-----BEGIN PGP SIGNATURE-----

iQJHBAABCgAxFiEEL4Gv+6sE4R/o7mXUJDrPqVH3jgEFAl7cGqwTHHR3QHdhbGRt
YW5uLWVkdi5kZQAKCRAkOs+pUfeOAd9ND/4nm2O7CK5a4aK41jAI1NisbgEtEJup
SiD6bvMKpo3VU0P/3Y6pUibKOGzaRImBTB04qS3LlgjB0mCp1RSVsj/Hn+yCNw+k
hfUH7E7JgAkq96Vkv1dcYgaJ9nhzuIAkEf0aDyzSo8HkBvGGN0/tfCQ7Nr7hI21u
v5qupIyu7KZrBwY389l7+6yJ9G5qCtHU0fDALRYyjsX+WphrAaizrhFZJO7Km8VZ
gZhAz3WUDPFwgNMb1mToUxpI2ZpnYnRxVBwjnX0Ps77ua4F5OsYM+hYwH5eX9bS9
gmb+W3NjUNjVVj4z+OgN8FGbCTeFVQ6E+IVdm55D4ZRU8KarvFoKOI7HS4GP/3iv
4iWqDaYBMRShnUTk1FKFCKjTb5tXewUGPwio+4bpgUyfJj0OWj1ecMqeF5VAslWz
6pZnsUqLpTFuHUA6dr18TKX4U+c6rdXVM7BhNZe2XtjaQwau6Wz9nC1xhZyFNl1q
CHY7jmLhsfP8GXkh31X9bJrKSZMyYRYat2e7kOroIJczRcHG9T708T+KzsfAb+6w
pWZbfWNfCbCmVQehyhDvNepB3IB5w6ijrZwKTamHAnYBVkAUD/aYwDQJf4nAL4YI
7JXBRpLlCVQGRUQdClqy8QjzpSZs5/Dbetvy5of753JbVjFQtGO2gLLp0wL0HB0v
vIZv3dfBDvfcXQ==
=F4gj
-----END PGP SIGNATURE-----
user@disp5066:~$ 

Pip也没有办法将用于签署软件包的gpg密钥标记为“官方”密钥,因此您必须希望作者已在几个不同的域中发布了他们的密钥,以便您可以通过多种方式获取并确认其正确性,然后导入并信任它。之后,您可以使用gpg来验证从PyPI下载的文件的签名。
gpg --verify borgbackup-1.1.13.tar.gz.asc 

另见:
  1. https://github.com/borgbackup/borg/issues/4213
  2. https://security.stackexchange.com/questions/232855/does-pythons-pip-provide-cryptographic-authentication-and-integrity-validation

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接