15

我刚刚被指出一篇非常有趣的文章已归档),该文章是关于名为 Cross Build Injection (XBI) 的安全问题。基本上,它是一个花哨的名称,用于在构建时通过自动构建系统(如 ant、maven 或 ivy)将不良代码走私到应用程序中。

这个问题可以通过引入加密签名验证来缓解依赖关系,因为它目前已在许多操作系统中用于下载包。

需要明确的是:我不是在谈论简单地为工件提供 md5 或 sha1 哈希。这已经完成了,但是这些哈希存储在与工件相同的位置。因此,一旦恶意黑客破坏了存储库并可以替换工件,他们也可以替换哈希值。

所以真正需要的是某种 PKI,它允许开发人员签署他们的工件和 maven 来验证这些签名。由于签名是使用开发人员的私钥完成的,因此只有存储库被破坏时,它不能被篡改。

有谁知道这个在maven中的状态?

4

4 回答 4

9

tl;博士

Maven 中不存在的验证机制和 POM 的 DSL 中缺少语言结构是严重的安全威胁。在解决MNG-6026之前,请使用Gradle Witness之类的东西。

介绍

到目前为止提供的答案似乎都没有解决问题。签署工件只是朝着正确方向迈出的第一步。但是,用于签署工件的密钥被认为是可信/有效的条件是非常不透明的。例如:pgpverify-maven-pluginNexus Professional如何真正验证签名对工件有效?仅从密钥服务器检索密钥并验证工件是不够的。

Sonatype 在他们的博客文章中简要提到了这一点:

PGP 签名:另一个层次

在消费方面,您可以使用 Nexus Professional 中的采购来检查是否存在签名,而在发布方面,使用 PGP 签名对您的发布进行签名并在公钥服务器上提供 PGP 签名将帮助人们仔细检查工件并且校验和是一致的。注意:我认为创建鼓励使用 PGP 密钥的工具还有更多工作要做,更重要的是,让存储库管理员可以控制哪些密钥是可信的。

(强调我的)

使用信任信息扩展项目对象模型 (POM)

我们需要的是建模从您的项目或工件到声明的依赖关系的信任关系的可能性。因此,如果所有相关方都声明了这种关系,我们就能够创建一个“信任链”,从根(例如项目)开始,一直到其依赖关系,直至最后一个传递依赖关系。项目对象模型 (POM)需要通过 <verification/> 元素来扩展依赖项。

现在的情况

现在我们有类似的东西

<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.0</version>
</dependency>

硬依赖

对于硬依赖,<verfication/> 可以包含 artifact 的 sha256sum 及其 POM 文件:

<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.0</version>
  <verification>
    <checksum hash='sha-256'>
      <pom>[sha256 of junit pom file]</pom>
      <artifact>[sha256sum of artifact (junit.jar)]</artifact>
    </checksum>
  </verification>
</dependency>

软依赖

如果使用软依赖或范围依赖,那么我们可以指定用于签署工件的密钥对的公钥(或多个)

<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>[4.0,4.5)</version>
  <verification>
    <openpgp>[secure fingerprint of OpenPGP key]</openpgp>
    <!-- possible further 'openpgp' elements in case the artifacts in the
         specified version range where signed by multiple keys -->
  </verification>
</dependency>

现在?

感谢peter触发我,我提出了 Apache Maven 的功能请求:MNG-6026。让我们看看接下来会发生什么。

其他方法

Gradle Witness为 gradle 做了类似的事情。但它有一些缺点:

  • 它建立在 gradle 之上(并且内置在 POM 中)
  • 它只允许硬依赖,因为它使用哈希。

Maven Enforcer Plugin似乎也是如此。

pgpverify-maven-plugin 显然也遵循这种方法。尽管缺少文档,但对所谓的keysMap属性进行了测试,该属性在配置文件中keysMapLocation也显示为.

于 2016-01-14T16:58:57.833 回答
7

更新:下面提到的校验和确实仅用于完整性检查,并且确实与工件一起存储,因此它们不回答问题。

实际上,需要使用 PGP 对工件进行签名,以将它们上传到与中央同步的存储库(Maven GPG 插件可以帮助完成这一步骤)。要在下载时验证签名,请使用支持此功能的存储库管理器。从如何使用 Maven 生成 PGP 签名

如果您使用从中央 Maven 存储库下载工件的工具,则需要确保您正在努力验证这些工件是否具有有效的 PGP 签名,该签名可以通过公钥服务器进行验证。如果您不验证签名,则无法保证您下载的是原始工件。验证工件签名的一种方法是使用存储库管理器,如 Nexus Professional。在 Nexus Professional 中,您可以配置采购套件以检查每个下载的工件是否有有效的 PGP 签名,并根据公钥服务器验证签名。

如果您使用 Maven 开发软件,您应该为您的版本生成 PGP 签名。发布具有有效签名的软件意味着您的客户可以验证软件工件是否由原始作者生成,并且在传输过程中未被任何人修改。像 Apache 软件基金会这样的大多数大型 OSS 锻造要求所有项目都由发布经理发布,其密钥已由组织的其他成员签名,如果您想将软件工件同步到 Maven 中心,则需要 提供 pgp 签名.

也可以看看


可以将 Maven 安装插件配置为创建完整性校验和(MD5、SHA-1),并且您可以为每个存储库配置校验和策略(请参阅 参考资料checksumPolicy)。

Maven 存储库管理器可以/应该也能够处理它们。参见例如:

于 2010-07-22T14:16:02.017 回答
1

现在可以使用此插件在 Maven 中验证 PGP 签名:https ://www.simplify4u.org/pgpverify-maven-plugin/index.html

以下是在您的父母中配置它的方法pom.xml

<build>
    <plugins>

        <plugin>
            <groupId>org.simplify4u.plugins</groupId>
            <artifactId>pgpverify-maven-plugin</artifactId>
            <version>1.5.1</version>
            <configuration>
                <pgpKeyServer>https://pgp.mit.edu</pgpKeyServer>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>check</goal>
                    </goals>
                    <phase>install</phase>
                </execution>
            </executions>
        </plugin>           

    </plugins>

</build>

此配置将 PGP 检查绑定到install阶段。

如果您不想一直运行检查,请删除该<executions />元素并手动运行它,如下所示:

mvn org.simplify4u.plugins:pgpverify-maven-plugin:check
于 2014-08-15T00:19:44.383 回答
0

“这个问题可以通过引入加密签名验证来缓解依赖关系,因为它目前已在许多操作系统中用于下载包。”

您正在寻找什么来签署您的 jar 文件。 http://download-llnw.oracle.com/javase/1.3/docs/tooldocs/win32/jarsigner.html

您需要采取适当措施保护您的私钥。但是,如果您对这样的镇静感到偏执,您可能需要查看 PKI,公钥基础设施。

于 2010-07-29T10:38:56.087 回答