Przejęte zależności Gradle stanowią zagrożenie dla bezpieczeństwa. Osoba o złośliwych zamiarach może wstrzyknąć zmodyfikowaną zależność do procesu kompilacji, na przykład za pomocą ataku typu „man in the middle” podczas rozwiązywania zależności.
Jeśli zależność kompilacji (biblioteka) została naruszona, może to wpłynąć na sposób wykonywania aplikacji na urządzeniu. Jeśli zależność wtyczki została naruszona, może to zmienić sposób działania kompilacji lub nawet uruchomić na maszynie kompilacyjnej zewnętrzne polecenia.
Aby temu zapobiec, możesz włączyć w swojej kompilacji weryfikację zależności.
Suma kontrolna i podpis biblioteki
Autorzy bibliotek mogą udostępnić 2 elementy metadanych, które pomogą Ci zweryfikować autentyczność pobieranych zależności. Aby określić, które wartości są akceptowane, zdefiniuj plik o nazwie gradle/verification-metadata.xml
. Może zawierać:
Sumy kontrolne – hasz artefaktu, którego możesz użyć do sprawdzenia, czy artefakt nie został uszkodzony podczas przesyłania. Jeśli zweryfikowana suma kontrolna pochodzi z zaufanego źródła, oznacza to, że artefakt nie uległ zmianie, co zmniejsza ryzyko ataków typu „człowiek w środku”.
Minusem jest to, że sumy kontrolne są obliczane na podstawie artefaktów, a te zmieniają się z każdą wersją, co wymaga aktualizacji
gradle/verification-metadata.xml
za każdym razem, gdy je aktualizujesz.Podpisy – umożliwia użytkownikom zależności określenie klucza publicznego dla danego artefaktu w celu potwierdzenia, że został on utworzony i podpisany przez autora biblioteki, który jest uwierzytelnionym właścicielem tego klucza publicznego. To więcej pracy dla autora biblioteki, ale dopóki jego klucz prywatny nie zostanie skompromitowany, podpis potwierdza, że biblioteka jest legalna.
Jeśli autor biblioteki podpisuje każdą wersję artefaktu tym samym kluczem, nie musisz aktualizować
gradle/verification-metadata.xml
podczas ich uaktualniania.
Włącz weryfikację zależności
Weryfikacja zależności Gradle porównuje sumy kontrolne i podpisy podczas kompilacji.
Utwórz plik gradle/verification-metadata.xml
zawierający te informacje:
<?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>
Jest to punkt wyjścia, który wkrótce zostanie zaktualizowany.
Uruchom ./gradlew assembleDebug
, aby sprawdzić, jak to wpływa na kompilację. Zobaczysz takie komunikaty:
* 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 informuje, że pobierasz wersje zależności, których nie zatwierdziłeś wyraźnie.
Wstępna konfiguracja danych kontrolnych i podpisów
Możesz uruchomić początkowy zestaw zaufanych kluczy i komponentów. W ramach tego procesu są pobierane bieżące podpisy i sumy kontrolne wszystkich bibliotek używanych w projekcie.
Wygeneruj początkowe metadane, wykonując
./gradlew --write-verification-metadata pgp,sha256 --export-keys help
To polecenie informuje Gradle, aby utworzył listę kluczy PGP i wartości kontrolnych dla wszystkich zależności używanych w tym projekcie. W pliku verification-metadata.xml zobaczysz zmiany, w tym:
<trusted-key id="8461EFA0E74ABAE010DE66994EB27DB2A3B88B8B">
<trusting group="androidx.activity"/>
</trusted-key>
Informuje Gradle, że jeśli zobaczy zależność z grupy Mavenandroidx.activity
, musi upewnić się, że towarzyszące pliki .asc (podpisy przechowywane w repozytorium) pasują do tego klucza.
Bootstrapping wygeneruje też gradle/verification-keyring.keys
zawierający publiczne klucze PGP używane przez kompilację. Prześlij oba te pliki do systemu śledzenia wersji. Wszystkie przyszłe zmiany, które modyfikują verification-metadata.xml
lub verification-keyring.keys
, powinny być dokładnie sprawdzane.
Usuwanie wersji z zaufanych kluczy
Klucze podpisywania rzadko się zmieniają między wersjami biblioteki. Wygenerowane dane w pliku gradle/verification-metadata.xml
zawierają szczegóły wersji, co oznacza, że musisz ponownie dodać kluczowe informacje o każdej nowej wersji zależności.
Aby tego uniknąć i określić, że klucz ma zastosowanie do wszystkich wersji biblioteki, usuń specyfikacje wersji.
W edytorze Android Studio użyj opcji Edytuj > Znajdź > Zamień…, aby za pomocą wyrażenia regularnego zastąpić wszystkie specyfikacje wersji zaufanych kluczy.
- from:
<trusted-key(.*) version=\".*\"/>
- do:
<trusted-key$1/>
Synchronizacja w Android Studio
Do tej pory kompilacja z poziomu wiersza poleceń działa, ale jeśli spróbujesz zsynchronizować w Android Studio, zobaczysz błędy takie jak
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 chce pobrać źródła Gradle (wraz z innymi źródłami i dokumentami). Najprostszym sposobem na rozwiązanie tego problemu jest zaufanie do wszystkich źródeł i javadocs.
Dodaj <trusted-artifacts>
w 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>
Kompilacja będzie teraz działać prawidłowo z poziomu wiersza poleceń i Android Studio.