Las dependencias de Gradle comprometidas representan un riesgo de seguridad. Un actor malicioso podría insertar una dependencia modificada en el proceso de compilación, por ejemplo, a través de un ataque de intermediario durante la resolución de dependencias.
Si se vulnera una dependencia de compilación (una biblioteca), puede afectar la forma en que tu aplicación se ejecuta en un dispositivo. Si se vulnera una dependencia de complemento, puede cambiar la forma en que funciona tu compilación o incluso ejecutar comandos externos en la máquina de compilación.
Para mitigar esto, puedes habilitar la verificación de dependencias en tu compilación.
Sumas de comprobación y firmas de bibliotecas
Los autores de bibliotecas pueden proporcionar dos metadatos que pueden ayudar a verificar la autenticidad de las dependencias que descargas. Define un archivo llamado gradle/verification-metadata.xml
para especificar qué valores apruebas. Puede contener lo siguiente:
Sumas de comprobación: Es un hash de un artefacto que puedes usar para verificar que no se dañó durante el transporte. Si la suma de verificación se recuperó de una fuente confiable, te indica que el artefacto no cambió, lo que reduce los ataques de intermediario.
La desventaja es que, como las sumas de comprobación se calculan a partir de los artefactos, cambian con cada versión, lo que requiere que actualices
gradle/verification-metadata.xml
cada vez que los actualices.Firmas: Permite que los usuarios de dependencias especifiquen una clave pública para un artefacto determinado para validar que el autor de la biblioteca, que es el propietario autenticado de esa clave pública, lo haya compilado y firmado. Esto es más trabajo para el autor de la biblioteca, pero, siempre que su clave privada no se haya vulnerado, la firma te indica que la biblioteca es legítima.
Si el autor de la biblioteca firma cada versión de un artefacto con la misma clave, no es necesario que actualices
gradle/verification-metadata.xml
cuando los actualices.
Habilita la verificación de dependencias
La verificación de dependencias de Gradle compara las sumas de comprobación y las firmas durante la compilación.
Crea un archivo gradle/verification-metadata.xml
que contenga lo siguiente:
<?xml version="1.0" encoding="UTF-8"?>
<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 .pom and .module files -->
<verify-metadata>true</verify-metadata>
<!-- verify .asc PGP files that come with the artifacts -->
<verify-signatures>true</verify-signatures>
<!-- use human readable keyring format -->
<keyring-format>armored</keyring-format>
<!-- read keys in a local file, fewer requests to network -->
<key-servers enabled="false">
<key-server uri="https://keyserver.ubuntu.com"/>
<key-server uri="https://keys.openpgp.org"/>
</key-servers>
</configuration>
<components>
</components>
</verification-metadata>
Esto sirve como punto de partida y se actualizará en breve.
Ejecuta ./gradlew assembleDebug
para ver cómo cambia la compilación. Verás mensajes como los siguientes:
* What went wrong:
Error resolving plugin [id: 'com.android.application', version: '8.7.3', apply: false]
> Dependency verification failed for configuration 'detachedConfiguration1'
One artifact failed verification: com.android.application.gradle.plugin-8.7.3.pom ...
This can indicate that a dependency has been compromised ...
Open this report for more details: .../dependency-verification-report.html
Gradle te indica que estás extrayendo versiones de dependencias que no aprobaste de forma explícita.
Inicializa la suma de comprobación y los datos de la firma
Puedes inicializar el conjunto inicial de claves y componentes de confianza. Este proceso recopila las firmas y sumas de comprobación actuales de todas las bibliotecas que usa tu proyecto.
Ejecuta el siguiente comando para generar los metadatos iniciales:
./gradlew --write-verification-metadata pgp,sha256 --export-keys help
Este comando le indica a Gradle que compile una lista de claves PGP y sumas de comprobación de resguardo para todas las dependencias que se usan en este proyecto. Verás un cambio en verification-metadata.xml con varias entradas, como las siguientes:
<trusted-key id="8461EFA0E74ABAE010DE66994EB27DB2A3B88B8B">
<trusting group="androidx.activity"/>
</trusted-key>
Esto le indica a Gradle que, si ve una dependencia del grupo de Maven androidx.activity
, se asegurará de que los archivos .asc adjuntos (firmas almacenadas en el repositorio) coincidan con esa clave.
El inicio también generará gradle/verification-keyring.keys
, que contiene las claves públicas de PGP que usa tu compilación. Verifica ambos archivos en tu sistema de seguimiento de versiones. Cualquier cambio futuro que modifique verification-metadata.xml
o verification-keyring.keys
debe revisarse cuidadosamente.
Quita las versiones de las claves de confianza
Las claves de firma rara vez cambian entre las versiones de una biblioteca. Los datos generados en
el archivo gradle/verification-metadata.xml
contienen detalles de la versión, lo que significa
que deberás volver a agregar información clave para cada versión nueva de dependencia.
Para evitar esto y especificar que la clave se aplica a todas las versiones de una biblioteca, quita las especificaciones de versión.
En el editor de Android Studio, usa Edit > Find > Replace… con una expresión regular para reemplazar todas las especificaciones de versión de las claves de confianza.
- de:
<trusted-key(.*) version=\".*\"/>
- a:
<trusted-key$1/>
Sincronización de Android Studio
Hasta ahora, tu compilación de línea de comandos funciona, pero si intentas sincronizarla en Android Studio, verás errores como los siguientes:
A build operation failed.
Dependency verification failed for configuration ':app:detachedConfiguration3'
One artifact failed verification: gradle-8.10.2-src.zip (gradle:gradle:8.10.2) from repository Gradle distributions
If the artifacts are trustworthy, you will need to update the gradle/verification-metadata.xml file. For more on how to do this, please refer to https://docs.gradle.org/8.10.2/userguide/dependency_verification.html#sec:troubleshooting-verification in the Gradle documentation.
Android Studio quiere descargar las fuentes de Gradle (junto con otras fuentes y documentos). La forma más fácil de corregir esto es confiar en todas las fuentes y javadocs.
Agrega <trusted-artifacts>
en gradle/verification-metadata.xml
:
<verification-metadata ...>
<configuration>
<trusted-artifacts>
<trust file=".*-javadoc[.]jar" regex="true"/>
<trust file=".*-sources[.]jar" regex="true"/>
<trust group="gradle" name="gradle"/>
</trusted-artifacts>
...
</configuration>
</verification-metadata>
Tu compilación ahora funcionará correctamente desde la línea de comandos y Android Studio.