Checkmarx最近对Python生态系统 的 调查发现了一个长期存在的设计问题,在运行 pip install 和 pip download时都会导致恶意代码的执行 。
问题出在setup.py最初的设计方式上。Setup.py通常作为设置脚本捆绑在Python包中,其目的是提供元数据,如所有包的需求/依赖的列表。不幸的是,它也是不良分子实现其恶意代码的地方。在这种情况下, 如果恶意代码与你的软件包一起安装恶意软件,仅仅运行 pip install 就足以危害你的机器。
然而,更令人担忧的是,简单地运行 pip下载 就足以调用setup.py,这也可能导致执行恶意代码。大多数用户会惊讶地发现,仅仅下载一个包就会导致执行代码,但这是设计好的,因为为了使用该包,所有的需求/依赖也需要被下载。同样,要下载的依赖项列表可以通过运行setup.py获得。
好消息是,大多数软件包都是以轮子(.whl)形式安装的,这是pip首先寻找的软件包的默认格式。轮子不需要执行setup.py。不幸的是,轮子并不是万能的,因为:
- 并非所有的软件包都可以作为轮子使用。
- 轮子既没有签名,也不一定是安全构建的,而且本身可能包含恶意软件。虽然Python软件包索引(PyPI)确实扫描了恶意软件,但它 并不总是能有效地 找到它。
确保软件供应链的安全
Python 生态系统并不是唯一容易受到这类供应链攻击的地方。大多数公共资源库不提供签名代码,也不对他们提供的第三方软件包的安全性和完整性提供任何保证。
这使得每一个有安全意识的组织都要实施他们自己的一套检查和平衡,以确保他们进口、建立和使用的第三方代码不会损害他们的系统和软件。但所有这些控制措施的实施以及维护、升级和审计的成本都是非常高的。
这是一个问题,ActiveState一直在用我们的ActiveState平台来解决这个问题。ActiveState平台维护自己的开源资产目录,并使用它们以安全的方式从源代码(包括链接的C库)自动构建开源包。因此,它为开发者提供了一个自动化的、交钥匙的解决方案,可以通过提供以下内容帮助保护你的Python、Perl、Ruby和Tcl供应链。
- 安全导入过程:我们的自动化系统会定期检查上游的开源仓库,查看任何新发布的或新版本的软件包。如果发现,它将:
- 同时下载源代码和相关元数据。
- 对源代码进行静态分析,以确保我们关于它的数据是完整的,然后再把它插入我们的目录中。
- 检查流行的漏洞数据库,以便我们能够用CVE信息增加我们的元数据。
- 定期监测我们摄入的源代码,如果发现它包含木马、恶意软件等,则将其从目录/管道中删除。
- 安全构建服务:我们的自动构建服务在云端运行,在一组最小的预定义的、锁定的资源上运行,以最大限度地减少攻击面。该服务包含了:
- 构建不能在构建服务中被访问和修改的脚本,防止被利用。
- 短暂的、孤立的构建步骤,在它们自己的容器中执行,在每个步骤完成后被丢弃。换句话说,容器是专门为执行单一功能而设计的,减少了被破坏的可能性。
- 没有互联网接入的密封环境,防止(例如)动态包包括远程资源。
- 可重复的构建,其中构建过程是安全的,如果在构建步骤中产生的任何组件未能通过其校验和验证,则终止构建。
对于setup.py构成的特定威胁,ActiveState平台通过在一个孤立的短暂构建步骤中运行setup.py来提供保护,因此当你使用ActiveState的软件包管理器State Tool将其安装在你的机器上时,它永远不会被运行。