Проверка зависимостей, Проверка зависимостей

Скомпрометированные зависимости Gradle представляют угрозу безопасности. Злоумышленник потенциально может внедрить измененную зависимость в процесс сборки, например, посредством атаки «человек посередине» во время разрешения зависимостей.

Если зависимость сборки (библиотека) была скомпрометирована, это может повлиять на работу вашего приложения на устройстве. Если зависимость плагина была скомпрометирована, это может изменить способ работы вашей сборки или даже запустить внешние команды на машине сборки.

Чтобы смягчить это, вы можете включить проверку зависимостей в своей сборке.

Контрольные суммы и подписи библиотеки

Авторы библиотеки могут предоставить два фрагмента метаданных, которые помогут проверить подлинность загружаемых вами зависимостей. Вы определяете файл с именем gradle/verification-metadata.xml чтобы указать, какие значения вы одобряете. Он может содержать:

  • Контрольные суммы — хэш артефакта, который можно использовать для проверки того, что артефакт не был поврежден во время транспортировки. Если контрольная сумма была получена из надежного источника, это говорит о том, что артефакт не изменился, что снижает вероятность атак «человек посередине».

    Обратной стороной является то, что, поскольку контрольные суммы рассчитываются на основе артефактов, они меняются с каждым выпуском, что требует обновления gradle/verification-metadata.xml при каждом их обновлении.

  • Подписи — позволяет пользователям зависимостей указывать открытый ключ для данного артефакта, чтобы подтвердить, что этот артефакт был создан и подписан автором библиотеки, который является аутентифицированным владельцем этого открытого ключа. Это дополнительная работа для автора библиотеки, но до тех пор, пока сам его закрытый ключ не был скомпрометирован, подпись говорит о том, что библиотека является законной.

    Если автор библиотеки подписывает каждую версию артефакта одним и тем же ключом, вам не нужно обновлять gradle/verification-metadata.xml при их обновлении.

Включить проверку зависимостей

Проверка зависимостей Gradle сравнивает контрольные суммы и подписи во время сборки.

Создайте файл gradle/verification-metadata.xml , содержащий следующее:

<?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>

Это служит отправной точкой и будет обновлено в ближайшее время.

Запустите ./gradlew assembleDebug чтобы увидеть, как это изменит сборку. Вы увидите такие сообщения, как

* 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 сообщает вам, что вы подключаете версии зависимостей, которые вы явно не одобрили.

Загрузите контрольную сумму и данные подписи.

Вы можете загрузить исходный набор доверенных ключей и компонентов. Этот процесс собирает текущие подписи и контрольные суммы для всех библиотек, используемых вашим проектом.

Сгенерируйте исходные метаданные, запустив

./gradlew --write-verification-metadata pgp,sha256 --export-keys help

Эта команда сообщает Gradle создать список ключей PGP и резервных контрольных сумм для всех зависимостей, которые используются в этом проекте. Вы увидите изменение в файлеverification-metadata.xml с рядом записей, например:

<trusted-key id="8461EFA0E74ABAE010DE66994EB27DB2A3B88B8B">
    <trusting group="androidx.activity"/>
</trusted-key>

Это сообщает Gradle, что если он увидит зависимость от группы maven androidx.activity , он гарантирует, что сопровождающие файлы .asc (подписи, хранящиеся в репозитории) соответствуют этому ключу.

При начальной загрузке также будет создан файл gradle/verification-keyring.keys , содержащий общедоступные ключи PGP, используемые вашей сборкой. Зарегистрируйте оба этих файла в своей системе отслеживания версий. Любые будущие изменения, которые изменяют файл verification-metadata.xml или verification-keyring.keys должны быть тщательно проверены.

Удаление версий из доверенных ключей

Ключи подписи редко меняются между выпусками библиотеки. Сгенерированные данные в файле gradle/verification-metadata.xml содержат сведения о версии. Это означает, что вам нужно будет повторно добавить ключевую информацию для каждой новой версии зависимостей.

Чтобы избежать этого и указать, что ключ применяется ко всем версиям библиотеки, удалите спецификации версии.

В редакторе Android Studio используйте «Правка» > «Найти» > «Заменить...», используя регулярное выражение, чтобы заменить все спецификации версий для доверенных ключей.

  • от: <trusted-key(.*) version=\".*\"/>
  • куда: <trusted-key$1/>

Синхронизация Android Studio

Пока что ваша сборка из командной строки работает, но если вы попытаетесь синхронизироваться в Android Studio, вы увидите такие ошибки, как

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 хочет загрузить исходные коды Gradle (вместе с другими источниками и документацией). Самый простой способ исправить это — доверять всем источникам и javadocs. Добавьте <trusted-artifacts> в 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>

Теперь ваша сборка будет правильно работать из командной строки и Android Studio.

,

Скомпрометированные зависимости Gradle представляют угрозу безопасности. Злоумышленник потенциально может внедрить измененную зависимость в процесс сборки, например, посредством атаки «человек посередине» во время разрешения зависимостей.

Если зависимость сборки (библиотека) была скомпрометирована, это может повлиять на работу вашего приложения на устройстве. Если зависимость плагина была скомпрометирована, это может изменить способ работы вашей сборки или даже запустить внешние команды на машине сборки.

Чтобы смягчить это, вы можете включить проверку зависимостей в своей сборке.

Контрольные суммы и подписи библиотеки

Авторы библиотеки могут предоставить два фрагмента метаданных, которые помогут проверить подлинность загружаемых вами зависимостей. Вы определяете файл с именем gradle/verification-metadata.xml чтобы указать, какие значения вы одобряете. Он может содержать:

  • Контрольные суммы — хэш артефакта, который можно использовать для проверки того, что артефакт не был поврежден во время транспортировки. Если контрольная сумма была получена из надежного источника, это говорит о том, что артефакт не изменился, что снижает вероятность атак «человек посередине».

    Обратной стороной является то, что, поскольку контрольные суммы рассчитываются на основе артефактов, они меняются с каждым выпуском, что требует обновления gradle/verification-metadata.xml при каждом их обновлении.

  • Подписи — позволяет пользователям зависимостей указывать открытый ключ для данного артефакта, чтобы подтвердить, что этот артефакт был создан и подписан автором библиотеки, который является аутентифицированным владельцем этого открытого ключа. Это дополнительная работа для автора библиотеки, но до тех пор, пока сам его закрытый ключ не был скомпрометирован, подпись говорит о том, что библиотека является законной.

    Если автор библиотеки подписывает каждую версию артефакта одним и тем же ключом, вам не нужно обновлять gradle/verification-metadata.xml при их обновлении.

Включить проверку зависимостей

Проверка зависимостей Gradle сравнивает контрольные суммы и подписи во время сборки.

Создайте файл gradle/verification-metadata.xml , содержащий следующее:

<?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>

Это служит отправной точкой и будет обновлено в ближайшее время.

Запустите ./gradlew assembleDebug чтобы увидеть, как это изменит сборку. Вы увидите такие сообщения, как

* 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 сообщает вам, что вы подключаете версии зависимостей, которые вы явно не одобрили.

Загрузите контрольную сумму и данные подписи.

Вы можете загрузить исходный набор доверенных ключей и компонентов. Этот процесс собирает текущие подписи и контрольные суммы для всех библиотек, используемых вашим проектом.

Сгенерируйте исходные метаданные, запустив

./gradlew --write-verification-metadata pgp,sha256 --export-keys help

Эта команда сообщает Gradle создать список ключей PGP и резервных контрольных сумм для всех зависимостей, которые используются в этом проекте. Вы увидите изменение в файлеverification-metadata.xml с рядом записей, например:

<trusted-key id="8461EFA0E74ABAE010DE66994EB27DB2A3B88B8B">
    <trusting group="androidx.activity"/>
</trusted-key>

Это сообщает Gradle, что если он увидит зависимость от группы maven androidx.activity , он гарантирует, что сопровождающие файлы .asc (подписи, хранящиеся в репозитории) соответствуют этому ключу.

При начальной загрузке также будет создан файл gradle/verification-keyring.keys , содержащий общедоступные ключи PGP, используемые вашей сборкой. Зарегистрируйте оба этих файла в своей системе отслеживания версий. Любые будущие изменения, которые изменяют файл verification-metadata.xml или verification-keyring.keys должны быть тщательно проверены.

Удаление версий из доверенных ключей

Ключи подписи редко меняются между выпусками библиотеки. Сгенерированные данные в файле gradle/verification-metadata.xml содержат сведения о версии. Это означает, что вам нужно будет повторно добавить ключевую информацию для каждой новой версии зависимостей.

Чтобы избежать этого и указать, что ключ применяется ко всем версиям библиотеки, удалите спецификации версии.

В редакторе Android Studio используйте «Правка» > «Найти» > «Заменить...», используя регулярное выражение, чтобы заменить все спецификации версий для доверенных ключей.

  • от: <trusted-key(.*) version=\".*\"/>
  • куда: <trusted-key$1/>

Синхронизация Android Studio

Пока что ваша сборка из командной строки работает, но если вы попытаетесь синхронизироваться в Android Studio, вы увидите такие ошибки, как

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 хочет загрузить исходные коды Gradle (вместе с другими источниками и документацией). Самый простой способ исправить это — доверять всем источникам и javadocs. Добавьте <trusted-artifacts> в 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>

Теперь ваша сборка будет правильно работать из командной строки и Android Studio.