Verification of dependency authenticity in Maven POM based automated build systems
Asked Answered
H

5

16

I was just pointed to a very interesting article (archived) about a security problem called Cross Build Injection (XBI). Bascially it is a fancy name for smuggling bad code into an application at build time via automated build systems such as ant, maven or ivy.

The problem could be alleviated by introducing a cryptographic signature validation für dependencies as it is currently in place with many operating systems for downloading packages.

To be clear: I am not talking about simply providing md5 or sha1 hashes for the artifacts. That is already done, but those hashes are stored in the same location as the artifacts. So once a malicious hacker compromises the repository and can replace the artifact they can replace the hashes as well.

So what is acutally needed is some kind of PKI, that allows the developers to sign their artifacts and maven to verify these signatures. Since the signature is done using the private key of the developer it cannot be tampered with when only the repository is compromised.

Does anyone know the state of this in maven?

Hanshansard answered 22/7, 2010 at 8:47 Comment(4)
am I the only one who finds this scenario pretty far-fetched?Centesimo
Related: #14214906Flatto
@SeanPatrickFloyd I think it is a serious attack vector of Maven POM based build systems. An attacker could inject you a modified artifact without you noticing, eventually resulting in executing malicious code at runtime. How is that pretty far-fetched?Laquanda
@Laquanda keep in mind that I commented that 6 years ago. Opinions and experiences changeCentesimo
N
7

Update: The checksums mentioned below are indeed only for integrity checks and are indeed stored with the artifacts so they don't answer the question.

Actually, one need to sign artifacts using PGP to upload them to a repository that is synced with central (the Maven GPG Plugin can help for this step). To verify signatures at download time, you are invited to use a repository manager supporting this feature. From How to Generate PGP Signatures with Maven:

If you use a tool that downloads artifacts from the Central Maven repository, you need to make sure that you are making an effort to validate that these artifacts have a valid PGP signature that can be verified against a public key server. If you don’t validate signatures, then you have no guarantee that what you are downloading is the original artifact. One way to to verify signatures on artifacts is to use a repository manager like Nexus Professional. In Nexus Professional you can configure the procurement suite to check every downloaded artifact for a valid PGP signature and validate the signature against a public keyserver.

If you are developing software using Maven, you should generate a PGP signature for your releases. Releasing software with valid signatures means that your customers can verify that a software artifact was generated by the original author and that it hasn’t been modified by anyone in transit. Most large OSS forges like the Apache Software Foundation require all projects to be released by a release manager whose key has been signed by other members of the organization, and if you want to synchronize your software artifacts to Maven central you are required to provide pgp signatures.

See also


The Maven Install Plugin can be configured to create integrity checksums (MD5, SHA-1) and you can configure a checksum policy per repository (see checksumPolicy).

Maven repository managers can/should also be able to deal with them. See for example:

Neogaea answered 22/7, 2010 at 14:16 Comment(5)
Hi Pascal, Have you read the article on XBI? From what I understand the checksums you mentioned are meant for pure integrity checks. While this is ok to check for data corruption during download it is not sufficient for security. I think the term "non-repudiation" would be correct here. You need to verify that, the artifact you are including was actually created by the project team and not by a malicious hacker who compromised their repository. This is no simple task since it requires some sort of PKI and facilites to cryptographically sign maven artifacts.Hanshansard
Nice answer. I was unaware that the Procurement suite in Nexus Pro can be configured in this way.Singley
Such a long post yet still to fails to answer the question. Not to mention that this post is repeated 1k times on the Internet. We don't really care about automatic signing when we can't do automatic veryfing. -1Drivel
And we can't afford to pay for some huge piece of crap like Nexus Professional to do such a simple task like signature veryfing. What a fail.Drivel
How does Nexus Professional determine if a signature is valid for a given dependency? What we need is the possibility to model a trust relation between artifacts. See also my answer.Laquanda
L
10

tl;dr:

Non-existent verification mechanisms in Maven and missing language constructs in the POM's DSL are a serious security threat. Until MNG-6026 is addressed, use someting like Gradle Witness.

Introduction

None of the answers provided so far seem to solve the problem. Signing artifacts is only a first step into the right direction. But the condition upon which a key used to sign the artifact is considered to be trusted/valid is very opaque, and sometimes even weak. For example: How does pgpverify-maven-plugin or Nexus Professional actually verify that the signature is valid for the artifact? Just retrieving the key from keyserver and verifying the artifact is no enough.

Sonatype mentions this briefly in their blog post:

PGP Signatures: Another Level

On the consumption side, you can use Procurement in Nexus Professional to check for the presence of a signature, and on the publishing side signing your releases with a PGP signature and making PGP signatures available on a public keyserver will help people double-check that artifacts and checksums are consistent. Note: I think there’s more work to be done to create tools that encourage the use of PGP keys and, more importantly, give repository administrators some control over what keys are to be trusted.

(emphasis mine)

Extending the Project Object Model (POM) with trust information

What we need is the possibility to model a trust relation from your project or artifact to the declared dependencies. So that, if all involved parties declare such a relation, we are able to create a "chain of trust" from the root (e.g. the project) over its dependencies down to the very last transitive dependency. The Project Object Model (POM) needs to be extended by a <verification/> element for dependencies.

Current Situation

Right now we have something like

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

Hard dependencies

For hard dependencies, <verfication/> could include the sha256sum of artifact and its POM file:

<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>

Soft dependencies

If soft or ranged dependencies are used, then we could specify the public key (or multiple) of the keypair used to sign the artifacts

<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>

And now?

Thanks to peter triggering me, I've raised a feature request for Apache Maven: MNG-6026. Let's see what happens next.

Other approaches

Gradle Witness does something similar for gradle. But it has some disadvantages:

  • It is built on top of gradle (and built in POM)
  • It does only allow hard dependencies, because it uses hashes.

The same seems to be true for the Maven Enforcer Plugin.

pgpverify-maven-plugin appearently also follows this approach. Although documentation is missing there is a test for a so called keysMap property, which also appears in the config file as keysMapLocation.

Laquanda answered 14/1, 2016 at 16:58 Comment(2)
I like this idea, especially the part with the soft dependencies. Did you create a feature request for it? If yes I have not found it on issues.apache.org/jira/browse/MNGPoppyhead
Flow, would you please add github.com/vlsi/vlsi-release-plugins#checksum-dependency-plugin to your answer? It is a superset of gradle-witness, and checksum-dependency-plugin enables to verify checksums for the plugins as well.Trial
N
7

Update: The checksums mentioned below are indeed only for integrity checks and are indeed stored with the artifacts so they don't answer the question.

Actually, one need to sign artifacts using PGP to upload them to a repository that is synced with central (the Maven GPG Plugin can help for this step). To verify signatures at download time, you are invited to use a repository manager supporting this feature. From How to Generate PGP Signatures with Maven:

If you use a tool that downloads artifacts from the Central Maven repository, you need to make sure that you are making an effort to validate that these artifacts have a valid PGP signature that can be verified against a public key server. If you don’t validate signatures, then you have no guarantee that what you are downloading is the original artifact. One way to to verify signatures on artifacts is to use a repository manager like Nexus Professional. In Nexus Professional you can configure the procurement suite to check every downloaded artifact for a valid PGP signature and validate the signature against a public keyserver.

If you are developing software using Maven, you should generate a PGP signature for your releases. Releasing software with valid signatures means that your customers can verify that a software artifact was generated by the original author and that it hasn’t been modified by anyone in transit. Most large OSS forges like the Apache Software Foundation require all projects to be released by a release manager whose key has been signed by other members of the organization, and if you want to synchronize your software artifacts to Maven central you are required to provide pgp signatures.

See also


The Maven Install Plugin can be configured to create integrity checksums (MD5, SHA-1) and you can configure a checksum policy per repository (see checksumPolicy).

Maven repository managers can/should also be able to deal with them. See for example:

Neogaea answered 22/7, 2010 at 14:16 Comment(5)
Hi Pascal, Have you read the article on XBI? From what I understand the checksums you mentioned are meant for pure integrity checks. While this is ok to check for data corruption during download it is not sufficient for security. I think the term "non-repudiation" would be correct here. You need to verify that, the artifact you are including was actually created by the project team and not by a malicious hacker who compromised their repository. This is no simple task since it requires some sort of PKI and facilites to cryptographically sign maven artifacts.Hanshansard
Nice answer. I was unaware that the Procurement suite in Nexus Pro can be configured in this way.Singley
Such a long post yet still to fails to answer the question. Not to mention that this post is repeated 1k times on the Internet. We don't really care about automatic signing when we can't do automatic veryfing. -1Drivel
And we can't afford to pay for some huge piece of crap like Nexus Professional to do such a simple task like signature veryfing. What a fail.Drivel
How does Nexus Professional determine if a signature is valid for a given dependency? What we need is the possibility to model a trust relation between artifacts. See also my answer.Laquanda
I
1

It is now possible to validate PGP signatures in maven by using this plugin: https://www.simplify4u.org/pgpverify-maven-plugin/index.html

Here's how to configure it in your parent 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>

This configuration binds the PGP check to the install phase.

If you don't want to run the check all the time, remove the <executions /> element and run it manually like so:

mvn org.simplify4u.plugins:pgpverify-maven-plugin:check
Incorruption answered 15/8, 2014 at 0:19 Comment(7)
How does pgpverify-maven-plugin determine if a signature is valid for a given dependency?Laquanda
@Flow: For each dependency the plugin retrieves the corresponding PGP signature file (.asc), extracts the public key ID from the signature file, contacts the key server (default is hkp://pool.sks-keyservers.net) to pull the public key, and finally uses the signature and public key to verify the downloaded artifact's integrity.Incorruption
Then this does not the answer the question. Because this process only verifies the signature. As you describe it, there is no benefit over performing checksum verification. Just as the checksum files, he detached OpenPGP signature is still prone to manipulation. Have a look at my answer for more information.Laquanda
@Flow: You are right - a MITM attacker could sign the modified jar with their private key and upload their public key to the key server, causing the modified signature to verify successfully. I didn't think of that right away.Incorruption
Perhaps this plugin could be improved by allowing the user to specify a list of trusted key IDs. Then the plugin would verify signatures by using only the trusted keys, which would address the problem of an attacker using an unknown key pair to sign a hacked jar.Incorruption
I believe this functionality is already there. See for example github.com/s4u/pgpverify-maven-plugin/blob/… and github.com/s4u/pgpverify-maven-plugin/blob/…Laquanda
I was started to build map for pgpverify-maven-plugin with connecting maven artifact with pgp key which should be used for signing. You can see project at github.com/s4u/pgp-keys-mapAthalie
M
0

"The problem could be alleviated by introducing a cryptographic signature validation für dependencies as it is currently in place with many operating systems for downloading packages."

What you are looking for signing your jar files. http://download-llnw.oracle.com/javase/1.3/docs/tooldocs/win32/jarsigner.html

You need to protect your private key with appropriate measures. But if you are paranoid about such a composure you may need to look about PKI , Public Key Infrastructures.

Mollie answered 29/7, 2010 at 10:38 Comment(2)
Thanks Atilla. That is essentially what I mean. What I am concerned about is whether maven does implement such measures or rather if it is planned.Hanshansard
I wonder if a simpler solution to all of this is for all jars in the central repo being signed by the repo admins with a shared certificate from a CA such as DigiCert, then a Maven plugin (not sure if it exists) could fail the build when an unsigned jar is downloaded.Reciprocal
Z
0

There is a new Maven plugin which provides integrity checking of dependency authencity.

https://github.com/chains-project/maven-lockfile

maven-lockfile is able to create lockfiles for Maven projects and to build according to the lockfile.

The version is beta, all feedback is welcome.

Zetana answered 14/6, 2023 at 12:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.