יחסי תלות שנחשפו ב-Gradle מהווים סיכון אבטחה. גורם זדוני עלול להחדיר תלות ששונתה לתהליך ה-build, למשל באמצעות התקפת אדם בתווך במהלך פתרון התלות.
אם יחסי התלות ב-build (ספרייה) נפרצו, הם עלולים להשפיע על אופן ההפעלה של האפליקציה במכשיר. אם יחסי התלות של הפלאגין נפרצו, הם עלולים לשנות את אופן הפעולה של ה-build, או אפילו להריץ פקודות חיצוניות במכונה ל-build.
כדי לצמצם את הבעיה, אפשר להפעיל את אימות יחסי התלות ב-build.
סיכומי ביקורת וחתימות של ספריות
מחברי הספריות יכולים לספק שני קטעי מטא-נתונים שיכולים לעזור לאמת את האותנטיות של יחסי התלות שאתם מורידים. מגדירים קובץ בשם gradle/verification-metadata.xml
כדי לציין אילו ערכים תאשרו. הוא יכול להכיל:
סיכומי ביקורת – גיבוב של פריט קוד שאפשר להשתמש בו כדי לוודא שהפריט לא פגום במהלך ההעברה. אם סיכום הביקורת אוחזר ממקור מהימן, סימן שהאובייקט לא השתנה, וכך ניתן לצמצם את ההתקפות מסוג אדם בתווך (Man-in-the-Middle).
החיסרון הוא שמכיוון שסכומי הביקורת מחושבים מהארטיפקטים, הם משתנים בכל גרסה, ולכן צריך לעדכן את
gradle/verification-metadata.xml
בכל פעם שמבצעים שדרוג.Signatures – מאפשרת למשתמשים בספריות תלויות לציין מפתח ציבורי לאובייקט נתון כדי לאמת שהאובייקט הזה נוצר ונחתם על ידי מחבר הספרייה, שהוא הבעלים המאומת של המפתח הציבורי הזה. זהו מאמץ נוסף שצריך לבצע מחבר הספרייה, אבל כל עוד המפתח הפרטי שלו לא נפרץ, החתימה מראה שהספרייה חוקית.
אם מחבר הספרייה חותם על כל גרסה של הארטיפקט עם אותו מפתח, לא צריך לעדכן את
gradle/verification-metadata.xml
כשמשדרגים אותם.
הפעלת אימות יחסי התלות
אימות יחסי התלות ב-Gradle משווה בין סיכומי ביקורת לחתימות במהלך ה-build.
יוצרים קובץ 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
כדי לראות איך השינוי הזה משפיע על ה-build. יוצגו לכם הודעות כמו
* 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 . הנלווים (חתימות שמאוחסנות במאגר) תואמים למפתח הזה.
תהליך ה-bootstrapping ייצור גם את הקובץ gradle/verification-keyring.keys
שמכיל את מפתחות ה-PGP הציבוריים שבהם ה-build משתמש. שומרים את שני הקבצים האלה במערכת למעקב אחרי גרסאות. חשוב לבדוק היטב שינויים עתידיים שמשנים את הערכים של verification-metadata.xml
או verification-keyring.keys
.
הסרת גרסאות ממפתחות מהימנים
מפתחות החתימה משתנים לעיתים רחוקות בין גרסאות של ספרייה. הנתונים שנוצרים בקובץ gradle/verification-metadata.xml
מכילים פרטי גרסה, כלומר תצטרכו להוסיף מחדש את פרטי המפתח לכל גרסה חדשה של התלות.
כדי למנוע זאת ולציין שהמפתח חל על כל הגרסאות של הספרייה, צריך להסיר את הגדרות הגרסה.
בעורך של Android Studio, משתמשים באפשרות Edit > Find > Replace… באמצעות ביטוי רגולרי כדי להחליף את כל הגרסאות של מפתחות מהימנים.
- מאת:
<trusted-key(.*) version=\".*\"/>
- אל:
<trusted-key$1/>
סנכרון ב-Android Studio
עד עכשיו, ה-build של שורת הפקודה פועל, אבל אם תנסו לסנכרן ב-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 (יחד עם מקורות ומסמכים אחרים). הדרך הקלה ביותר לתקן את הבעיה היא להעניק אמון לכל קובצי ה-source ו-javadoc.
מוסיפים את <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.