亚马逊AWS官方博客

使用 Amazon CodeArtifact 软件包组配置提高软件供应链的安全性

从今天开始,软件包存储库的管理员可以使用新的 AWS CodeArtifact 软件包组配置功能在一个地方管理多个软件包的配置。使用软件包组,您可以定义内部开发人员或上游存储库如何更新软件包。现在,您可以允许或阻止内部开发人员发布软件包,或者允许或阻止一组软件包进行上游更新。

CodeArtifact 是一项完全托管的软件包存储库服务,使组织可以轻松安全地存储和共享用于应用程序开发的软件包。您可以将 CodeArtifact 与常用的生成工具和软件包管理程序结合使用,例如 NuGetMavenGradlenpmyarnpiptwineSwift Package Manager

CodeArtifact 支持从 npmjs.commaven.orgpypi.org 等公共存储库按需导入软件包。这使贵组织的开发人员能够从一个单一事实来源(您的 CodeArtifact 存储库)获取所有软件包。

简单的应用程序通常包含数十个包。大型企业应用程序可能有数百个依赖项。这些包提供可解决常见编程难题(例如网络访问、加密函数或数据格式操作)的代码,从而帮助开发人员加快开发和测试过程。这些包可能由组织中的其他团队制作或由第三方(例如开源项目)维护。

为了最大限度地降低供应链攻击的风险,一些组织会手动审查内部存储库中提供的软件包以及有权更新这些软件包的开发人员。有三种方法可以更新存储库中的软件包。贵组织的选定开发人员可能会推送软件包更新。贵组织的内部软件包通常就是这种情况。软件包也可能从上游存储库导入。上游存储库可能是另一个 CodeArtifact 存储库,例如公司范围内批准的软件包的源代码或提供常见开源包的外部公共存储库。

下图显示了向开发人员公开软件包的不同可能性。

CodeArtifact 多存储库

管理存储库时,定义下载和更新软件包的方式至关重要。例如,允许从外部上游存储库安装或更新软件包会使您的组织遭受误植域名依赖关系混淆攻击。想象一下,一个不良行为者使用略有不同的名称发布了一个知名软件包的恶意版本。举例来说,恶意软件包使用 cofee-script 而不是 coffee-script,仅存在一个 “f” 的差别。 当您的存储库被配置为允许从上游外部存储库检索时,只需要一个注意力分散的开发人员在深夜工作,键入 npm install cofee-script 而不是 npm install coffee-script 即可向您的系统注入恶意代码。

CodeArtifact 为更新软件包的三种可能方式定义了三种权限。管理员可以允许阻止来自内部发布命令、内部上游存储库或外部上游存储库的安装和更新。

直到今天,存储库管理员还必须逐包管理这些重要的安全设置。在今天的更新中,存储库管理员可以一次为一组软件包定义这三个安全参数。这些软件包由其类型、命名空间和名称来标识。这项新功能在域级别运行,而不是在存储库级别上。它允许管理员跨其域中的所有存储库强制执行软件包组规则。他们不必在每个存储库中维护软件包原始控制配置。

让我们详细了解它是如何工作的
想象一下,我使用 CodeArtifact 管理一个内部软件包存储库,并且我只想分发经过我的组织审查的适用于 Python 的 AWS SDK(也称为 boto3)。

我导航到 AWS 管理控制台中的 CodeArtifact 页面,然后创建一个 python-aws 存储库,为内部开发人员提供经过审查的软件包。

CodeArtifact - 创建存储库

除了我创建的存储库之外,还会创建一个暂存存储库。来自 pypi 的外部包将首先暂存在 pypi-store 内部存储库中,在将它们提供给 python-aws 存储库之前,我将在那里对它们进行验证。我的开发人员将在这里进行连接以下载它们。

CodeArtifact - 常见存储库 - 软件包流程默认情况下,当开发人员针对 CodeArtifact 进行身份验证并键入 pip install boto3 时,CodeArtifact 将从公共 pypi 存储库中下载软件包,将它们暂存在 pypi-store 上,并在 python-aws 上复制它们。

CodeArtifact - pip 安装CodeArtifact - pip 安装后的软件包列表

现在,想象一下我想阻止 CodeArtifact 从上游外部 pypi 存储库获取软件包更新。我希望 python-aws 只提供我从 pypi-store 内部存储库中获得批准的软件包。

有了我们今天发布的新功能,我现在可以将此配置应用于一组软件包。我导航到我的域并选择软件包组选项卡。然后,我选择创建软件包组按钮。

我输入软件包组定义。此表达式定义了该组中包含哪些软件包。软件包使用三个组件的组合来标识:软件包格式、可选命名空间和名称。

以下是可用于每种允许组合的一些模式示例:

  • 所有软件包格式:/*
  • 特定的软件包格式:/npm/*
  • 软件包格式和命名空间前缀:/maven/com.amazon~
  • 软件包格式和命名空间:/npm/aws-amplify/*
  • 软件包格式、命名空间和名称前缀:/npm/aws-amplify/ui~
  • 软件包格式、命名空间和名称:/maven/org.apache.logging.log4j/log4j-core$

请您阅读文档,了解所有的可能性。

在我的示例中,没有 Python 包的命名空间概念,我希望该组包含所有名称以 boto3 开头的来自 pypi 的软件包。因此,我编写了 /pypi//boto3~

CodeArtifact - 软件包组定义

然后,我为我的软件包组定义安全参数。在此示例中,我不希望我所在组织的开发人员发布更新。我也不希望 CodeArtifact 从外部上游存储库获取新版本。我只想授权来自我的内部暂存目录的软件包更新。

我取消选中所有的从父级组继承复选框。我为发布外部上游选择阻止。我在内部上游上保留允许。然后,我选择创建软件包组

CodeArtifact - 软件包组安全配置

一旦定义,开发人员就无法安装与 python-aws 存储库中授权的版本不同的软件包版本。作为开发人员,当我尝试安装另一个版本的 boto3 软件包时,会收到一条错误消息。这是意料之中的,因为 boto3 软件包的更新版本在上游暂存存储库中不可用,并且存在阻止规则阻止从外部上游存储库获取软件包或软件包更新。

Code ARtifact - 使用存储库中尚不存在的软件包版本时安装会被拒绝

同样,假设您的管理员想要保护您的组织免受依赖项替代攻击。您所有的内部 Python 软件包名称都以您的公司名称(mycompany)开头。管理员想阻止开发人员意外地从 pypi.org 下载以 mycompany 开头的软件包。

管理员使用模式 /pypi//mycompany~publish=allowexternal upstream=blockinternal upstream=block 创建规则。使用这种配置,内部开发人员或您的 CI/CD 管道可以发布这些软件包,但是 CodeArtifact 不会从以 mycompany 开头的 pypi.org(如 mycompany.foomycompany.bar)中导入任何软件包。这样可以防止这些软件包受到依赖项替换攻击。

所有提供 CodeArtifact 的 AWS 区域均提供软件包组,无需额外付费。它可以帮助您更好地控制软件包和软件包更新如何进入您的内部存储库。它有助于防止各种供应链攻击,例如误植域名依赖关系混淆。这是一项额外的配置,您现在可以将其添加到基础设施即代码(IaC)工具中,以创建和管理您的 CodeArtifact 存储库。

立即前往配置您的第一个软件包组

— seb