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,如果 Gradle 看到 Maven 群組 androidx.activity
的依附元件,就會確保隨附的 .asc 檔案 (儲存在存放區中的簽名) 與該鍵相符。
引導程序也會產生 gradle/verification-keyring.keys
,其中包含版本使用的公開 PGP 金鑰。將這兩個檔案都提交至版本追蹤系統。日後若有任何變更會修改 verification-metadata.xml
或 verification-keyring.keys
,請務必仔細審查。
從信任的金鑰中移除版本
在程式庫的不同版本之間,簽署金鑰幾乎不會變更。gradle/verification-metadata.xml
檔案中產生的資料包含版本詳細資料,因此您必須為每個新的依附元件版本重新新增關鍵資訊。
如要避免這種情況,並指定金鑰套用至程式庫的所有版本,請移除版本規格。
在 Android Studio 編輯器中,使用規則運算式依序選取「Edit」>「Find」>「Replace...」,取代信任金鑰的所有版本規格。
- 來源:
<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 來源 (以及其他來源和文件)。修正這個問題最簡單的方法,就是信任所有來源和 Javadoc。在 gradle/verification-metadata.xml
中新增 <trusted-artifacts>
:
<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 正常運作。