
Software projects often rely on external code libraries, known as dependencies. Package managers, such as Gradle, allow developers to reference dependencies for their projects.
These dependencies simplify development, but also introduce risk as they download and include external code based on a project's configuration. 
Integrity checking is the step of verifying that the downloaded or included dependency code is exactly what the developer expects. Without this verification, the application cannot guarantee that the dependency is legitimate.

Failing to verify the integrity of dependencies before using them is a significant security problem. It exposes your application, and potentially your users, to several risks. The core issue is that you are running code from an untrusted source without checking it, effectively giving an attacker a direct pathway into your application.

This is often a key component of what is called a "supply chain attack." The attacker isn't directly attacking your application. Instead, they are attacking a component you use. This is an important consideration because the attack's source is less obvious. You might diligently secure your own code, but overlook the risk introduced by external dependencies.

== Ask Yourself Whether

* Your team or company has the security policy to enforce dependency verification.

There is a risk if you answer yes to any of these questions.

== Recommended Secure Coding Practices

Create a `verification-metadata.xml` in the `gradle` directory of your project.
Use `./gradlew --write-verification-metadata pgp,sha256 --export-keys` to bootstrap the file content with PGP key ids and SH256 checksums.
The `--export-keys` option creates a keyring file containing the identities of all the dependencies publishers trust.

Verify the identity of all publisher keys exported in the local keyring.
If you cannot verify publisher identities, fallback on checksum-based integrity verification.

Enabling dependency verification in Gradle will add extra friction to your development workflow.
Make sure your team is aware about this change and has a process to maintain the `verification-metadata.xml` as well as the trusted identities.

== Sensitive Code Example

[source,kotlin]
----
dependencies {
    implementation("com.example:a-dependency:1.0")
}

configurations { 
    all {
        resolutionStrategy {
            disableDependencyVerification() // Sensitive: dependency verification is disabled
        }
    }
}
----

Absence of a `verification-metadata.xml` file in the `gradle` directory of your project will also result in the Gradle build not verifying the integrity of the dependencies.

== Compliant Solution

[source,kotlin]
----
dependencies {
    implementation("com.example:adependency:1.0")
}
----

[source,xml]
----
<verification-metadata 
    xmlns="https://schema.gradle.org/dependency-verification" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="https://schema.gradle.org/dependency-verification https://schema.gradle.org/dependency-verification/dependency-verification-1.3.xsd">
   <configuration>
      <verify-metadata>true</verify-metadata>
      <verify-signatures>true</verify-signatures>
      <keyring-format>armored</keyring-format>
      <trusted-keys>
         <trusted-key id="FD8190C7D72E7DCD42582B1042677B9FC1DC2161" group="com.example" name="adependency"/>
      </trusted-keys>
   </configuration>
</verification-metadata>
----

include::../see.adoc[]

* Gradle - https://docs.gradle.org/current/userguide/dependency_verification.html[Verifying dependencies]

ifdef::env-github,rspecator-view[]

'''
== Implementation Specification
(visible only on this page)

=== Message

* Create a `verification-metadata.xml` file to verify these dependencies against a known checksum or signature
* Remove this call to `disableDependencyVerification()` so that dependencies are verified

=== Highlighting

* Highlight by order of priority 
    * The `dependencies` block if it exist
    * The `plugins` block if it exist
    * Raise a project-level issue is no `dependencies` or `plugins` block is found
* Highlight `disableDependencyVerification()`

endif::env-github,rspecator-view[]

