dependency-guard icon indicating copy to clipboard operation
dependency-guard copied to clipboard

Feature request: Support saving and checking hash or signature of dependency in report

Open art-shen opened this issue 1 year ago • 3 comments

dependency-guard does an awesome job of protecting projects from unwanted dependency changes.

But this way we know nothing about the actual dependency content and cannot protect against malicious supply chain attacks like the ones mentioned here:

  • https://blog.oversecured.com/Introducing-MavenGate-a-supply-chain-attack-method-for-Java-and-Android-applications/
  • https://blog.sonatype.com/malware-removed-from-maven-central
  • https://www.csoonline.com/article/654560/why-open-source-software-supply-chain-attacks-have-tripled-in-a-year.html

Of course, we can use Gradle's support for package signatures. But it's hard to use properly and not supported by many Gradle plugins and library providers (including many Google and JetBrains packages).

By simply saving and checking the dependency package hash along with the package, name, and version, we can verify that this dependency has not been unexpectedly replaced! Using a hashing algorithm like xxHash this would be very fast and provide an order of magnitude higher level of security for any Gradle build with a super simple setup.

Additionally, we can store and check the signature hash for packages that provide one. Using truncated hashes (like for git commits) it will not bloat the dependency reports too much.

All of this can be optional and opt-in, disabled by default.

If this idea is welcome, I would be happy to provide a prototype/mvp pull request.

art-shen avatar Feb 02 '24 16:02 art-shen

I agree that dependency verification is an important aspect of security. Gradle does provide the feature out of the box using: https://docs.gradle.org/current/userguide/dependency_verification.html#sub:enabling-verification. I don't find it very user friendly, but it does exist and work.

Adding this functionality to dependency-guard would increase the scope of this plugin which is something I'd want to try and avoid unless there is a community consensus.

Considerations: Dependency Guard also supports source based modules, not just artifacts which is a bit different. That being said, I don't know if it's a 100% fit, but I understand your request.

handstandsam avatar Feb 05 '24 19:02 handstandsam

@handstandsam I think this functionality fits well within the scope of the plugin, but I understand your concerns. I'll make an MVP pull request to show that it shouldn't significantly increase complexity and usability. Would you consider it?

art-shen avatar Feb 06 '24 11:02 art-shen

I'd personally find this valuable as well in a tool. Before you spend a ton of time doing it, I've got a bunch of questions/comments to discuss so we can make sure this is something that could be implemented, and something that makes sense in this tool. Here are a bunch of questions/comments I thought of:

  • How does someone verify the initial hashes as they are baselined? (What if you have a bad artifact to begin with?)
  • Will you hash local artifacts to verify they do compute to the correct hash? Do you have that algorithm? Will that come from the Gradle OSS plugin?
  • What type of hashes would it support? SHA256? SHA512? SHA1? MD5?
  • In the baseline file, how do you represent the hash+algorithm used? What is an example of what the baseline would look like? Example - Kotlin 1.9.22 https://repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.9.22/

This could be a format (just an example).

org.jetbrains.kotlin:kotlin-stdlib:1.9.22 8c1a267 SHA1
  • How would this work with modules = true? (Probably just not do anything for those, which makes sense to me)
  • Requirement: We have a baselineMap config parameter that allows you to map (transform) what is stored in your baseline file (see readme for example https://github.com/dropbox/dependency-guard/tree/main). How would it work for items that are filtered out with null? How would it work for items that are transformed in general, because we have no way of guaranteeing what those look like. (Example: Some people like to trim off versions when they release a lot of versions internally). Another Example: some dependencies a team may not desire to baseline/track.
  • How will this work with -SNAPSHOT versions?
  • Extra Feature Request - Could you somehow note which repository (if more than one, example: mavenCentral(), google()) it came from? I think that's almost as important as the hash (in terms of the plugin's goal of "guard against detecting unintentional dependency changes")
org.jetbrains.kotlin:kotlin-stdlib:1.9.22 8c1a267 SHA1 https://repo1.maven.org/maven2

Future Questions:

  • What is the performance overhead?
  • Requirement: It needs to have a hard toggle in the plugin configuration and off by default (for consistent usage) - Unless it's a new major version. (Which this might be with this big of a change)

handstandsam avatar Feb 07 '24 13:02 handstandsam