95 lines
4.1 KiB
Plaintext

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
* Dependencies are not verified because the "verification-metadata.xml" file is missing. Make sure it is safe here.
* This call disables dependencies verification. Make sure it is safe here.
=== Highlighting
* Raise a project-level issue if a `verification-metadata.xml` file is not present
* Highlight `disableDependencyVerification()` calls when they are encountered in `settings.gradle.kts` files
endif::env-github,rspecator-view[]