超越排除模式:具有优先级解决的安全存储库

超越排除模式:具有优先级解决的安全存储库

您可能还记得几周前新闻中提到的名称空间阴影(Namespace Shadowing),即“依赖混淆”攻击。我当时在博客上写过JFrog Artifactory的排除模式功能我们一直都有,而且一直都是为了保护你不受这种攻击。

由于这个主题是新闻,它引起了人们对排除模式特性的大量关注,显然使您的构建更加安全(您现在使用它,对吗?!),但也突出了该方法的一些缺点。

我们清楚地听到了你们的反馈。如果您的内部库不符合一小部分通用命名模式,您将不得不设置许多排除规则,这不是一种愉快的体验,还可能对性能产生影响。您需要在存储库级别上进行控制。你说对了。从Artifactory 7.16.3开始,你现在可以将本地或远程存储库标记为“优先级解决”

TL/DR:在包含私有包的存储库上选中这个复选框,Artifactory将不会在那里寻找这些包的新版本。

对于那些喜欢技术细节的人来说,这是它的工作原理:

当包管理器请求依赖项时,它将(在一般情况下)首先请求元数据(所有可用版本的列表),然后决定需要哪个版本(基于依赖项声明),然后请求特定的文件。

当您的包管理器被配置为使用Artifactory中的虚拟存储库时,该存储库指向一组本地和远程存储库。Artifactory将为客户端准备元数据,根据两个规则依次解析所有存储库中的所有文件:(1)在虚拟存储库的设置中设置的解析顺序;(2)始终在远程存储库之前查询本地存储库。

让我们考虑几个场景来进行演示。设置如下:

我们有一组用于提升管道的本地存储库和一个代理中央注册中心的远程存储库,所有这些都包含在一个虚拟存储库中。在虚拟存储库设置中定义的解析顺序如下:

  • 本地产品存储库
  • 本地暂存库
  • 本地开发存储库
  • 远程存储库

即使您将远程存储库置于本地存储库之上,也不用担心!Artifactory将负责重新安排顺序,总是首先从本地存储库解析。让我们在这个设置上运行一些场景。

场景1:列出外部依赖项的版本

  1. 用户定义依赖于“外部包”版本~1.0.0(任何向后兼容1.0.0的版本,即2.0.0之前的所有版本,但不包括2.0.0)
  2. 客户端请求包' external-package '上的元数据,范围在1.0.0到(但不包括)2.0.0之间。
  3. Artifactory检查所有三个本地存储库,无法找到external-package的现有元数据,因为它不存在。
  4. Artifactory检查远程存储库,在那里找到' external-package '的元数据(例如版本1.1.0和1.2.0)。
  5. 不需要合并元数据,按原样返回的中央注册中心元数据包含两个找到的版本。

超越排除模式

场景2:在不同的存储库中列出内部依赖项的不同版本

  1. 用户定义依赖于“外部包”版本~1.0.0(任何向后兼容1.0.0的版本,即2.0.0之前的所有版本,但不包括2.0.0)
  2. 客户端请求在1.0.0到(但不包括)2.0.0之间的包' internal-package '上的元数据。
  3. Artifactory检查所有三个本地存储库,在所有三个存储库中找到不同的元数据清单(假设prod包含版本1.1.0、1.2.0和1.3.0,staging包含版本1.4.0和1.5.0,dev包含版本1.6.0)。
  4. Artifactory检查远程存储库,没有找到“内部包”,无论是缓存还是在中央注册表中。
  5. 人工合并元数据,生成一个1.1.0到1.6.0版本的列表,因为它们都可以从我们的虚拟存储库中获取。

超越排除模式

场景3:命名空间阴影攻击

  1. 攻击者将我们的“内部包”的恶意版本作为1.7.0版本上传到外部存储库中。
  2. 用户定义依赖于“外部包”版本~1.0.0(任何向后兼容1.0.0的版本,即2.0.0之前的所有版本)
  3. 客户端请求包' internal-package '的元数据,范围在1.0.0到2.0.0之间。
  4. Artifactory检查所有三个本地存储库,在所有三个存储库中找到不同的元数据清单(假设prod包含版本1.1.0、1.2.0和1.3.0,staging包含版本1.4.0和1.5.0,dev包含版本1.6.0)。
  5. 由于在我们的远程存储库上没有定义排除模式(isk- isk), Artifactory检查它,并找到' internal-package '的元数据,列出了恶意版本1.7.0。
  6. 人工合并元数据,生成一个1.1.0到1.7.0版本的列表,因为它们都可以从我们的虚拟存储库中获取。
  7. 客户端解析最新版本(1.7.0)并被黑客攻击。

超越排除模式

标记存储库优先解决在解析虚拟存储库时,Flag优先于解析顺序。将存储库设置为优先级将导致元数据仅从具有此字段的存储库中合并,从而有效地取消了我们第三个示例中的步骤(e)(有效地将糟糕的场景3转换为良好的场景2),因此返回的元数据将仅列出6个版本,因此客户端不会知道恶意版本1.0.7,也不会请求它。

优先级解析标志

显然,即使将存储库设置为优先解决,如果工件没有在任何本地存储库中找到(如我们的第一个示例),则将在其他存储库中进行查找(未设置为优先级解析)(在中央注册中心中查找'外部包')。

虽然大多数时候您会为优先级解析设置一个本地存储库,但有时您有一个远程存储库,它代理一个受信任的Artifactory实例(可能是另一个开发站点?),因此也可以在远程存储库上设置优先级解析。

所以,继续吧,升级到最新版本的JFrog Artifactory并将带有内部依赖关系的存储库标记为“优先解决”,以防止命名空间阴影攻击。我们仍然强烈建议使用名称空间(或至少命名约定)限定内部依赖关系的作用域,并对其使用排除模式。