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

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

您可能还记得几周前的新闻中提到的名称空间阴影(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检查所有三个本地存储库,无法找到外部包的现有元数据,因为它不存在。
  4. Artifactory检查远程存储库,在那里找到“外部包”的元数据(例如版本1.1.0和1.2.0)。
  5. 不需要合并元数据,中心注册中心元数据按原样返回,包含找到的两个版本。

超越排除模式

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

  1. 用户定义依赖于“外部包”版本~1.0.0(与1.0.0向后兼容的任何版本,即到2.0.0的所有版本,但不包括2.0.0)
  2. 客户端请求包' internal-package '上的元数据,范围从1.0.0到(但不包括)2.0.0。
  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. Artifactory合并元数据,生成版本从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. 由于在我们的远程存储库(diskk -tisk)上没有定义排除模式,Artifactory检查它,并找到“内部包”的元数据,列出恶意版本1.7.0。
  6. Artifactory合并元数据,生成版本从1.1.0到1.7.0的列表,因为所有这些版本都可以从我们的虚拟存储库中获取。
  7. 客户端解析最新版本(1.7.0)并被黑客攻击。

超越排除模式

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

优先级决议标志

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

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

那么,请讲,升级到最新版本的JFrog Artifactory并将存储库与内部依赖项标记为“优先级解决方案”,以防止命名空间阴影攻击。我们仍然强烈建议使用命名空间限定内部依赖关系的范围(或者至少是命名约定),并对它们使用排除模式。