Xác minh phần phụ thuộc

Các phần phụ thuộc Gradle bị xâm phạm gây ra rủi ro bảo mật. Một đối tượng độc hại có thể chèn một phần phụ thuộc đã sửa đổi vào quy trình xây dựng, ví dụ: thông qua một cuộc tấn công xen giữa trong quá trình phân giải phần phụ thuộc.

Nếu một phần phụ thuộc bản dựng (thư viện) bị xâm phạm, thì điều này có thể ảnh hưởng đến cách ứng dụng của bạn thực thi trên một thiết bị. Nếu một phần phụ thuộc trình bổ trợ bị xâm phạm, thì phần phụ thuộc đó có thể thay đổi cách hoạt động của bản dựng hoặc thậm chí chạy các lệnh bên ngoài trên máy tạo bản dựng.

Để giảm thiểu vấn đề này, bạn có thể bật tính năng Xác minh phần phụ thuộc trong bản dựng.

Checksum và chữ ký thư viện

Tác giả thư viện có thể cung cấp hai phần siêu dữ liệu có thể giúp xác minh tính xác thực của các phần phụ thuộc mà bạn đang tải xuống. Bạn xác định một tệp có tên gradle/verification-metadata.xml để chỉ định những giá trị mà bạn phê duyệt. Tệp này có thể chứa:

  • Checksum (Tổng kiểm) – hàm băm của một cấu phần phần mềm mà bạn có thể dùng để xác minh rằng cấu phần phần mềm đó không bị hỏng trong quá trình truyền. Nếu được truy xuất từ một nguồn đáng tin cậy, thì tổng kiểm sẽ cho bạn biết rằng cấu phần phần mềm không thay đổi, giúp giảm các cuộc tấn công giả mạo.

    Nhược điểm là do tổng kiểm được tính toán từ các cấu phần phần mềm, nên tổng kiểm sẽ thay đổi theo mỗi bản phát hành, yêu cầu bạn phải cập nhật gradle/verification-metadata.xml mỗi khi nâng cấp các cấu phần phần mềm đó.

  • Chữ ký – cho phép người dùng phần phụ thuộc chỉ định một khoá công khai cho một cấu phần phần mềm nhất định để xác thực rằng cấu phần phần mềm này được tạo và ký bởi tác giả thư viện, là chủ sở hữu đã được xác thực của khoá công khai đó. Việc này sẽ khiến tác giả thư viện phải làm nhiều việc hơn, nhưng miễn là khoá riêng của họ không bị xâm phạm, thì chữ ký sẽ cho bạn biết thư viện đó là hợp lệ.

    Nếu tác giả thư viện ký từng phiên bản của một cấu phần phần mềm bằng cùng một khoá, thì bạn không cần cập nhật gradle/verification-metadata.xml khi nâng cấp các phiên bản đó.

Bật tính năng xác minh phần phụ thuộc

Tính năng xác minh phần phụ thuộc Gradle so sánh tổng kiểm và chữ ký trong quá trình tạo bản dựng.

Tạo tệp gradle/verification-metadata.xml chứa nội dung sau:

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

Đây là điểm xuất phát và sẽ sớm được cập nhật.

Chạy ./gradlew assembleDebug để xem cách thay đổi này ảnh hưởng đến bản dựng. Bạn sẽ thấy các thông báo như

* 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 đang thông báo cho bạn rằng bạn đang lấy các phiên bản phần phụ thuộc mà bạn chưa phê duyệt rõ ràng.

Khởi động dữ liệu tổng kiểm và chữ ký

Bạn có thể khởi động các thành phần và khoá đáng tin cậy trong tập hợp ban đầu. Quy trình này thu thập các chữ ký và tổng kiểm hiện tại cho tất cả thư viện mà dự án của bạn sử dụng.

Tạo siêu dữ liệu ban đầu bằng cách chạy

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

Lệnh này yêu cầu Gradle tạo danh sách khoá PGP và tổng kiểm dự phòng cho tất cả các phần phụ thuộc được sử dụng trong dự án này. Bạn sẽ thấy một thay đổi trong verification-metadata.xml với một số mục như:

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

Thao tác này cho Gradle biết rằng nếu thấy một phần phụ thuộc từ nhóm maven androidx.activity, Gradle sẽ đảm bảo rằng các tệp .asc đi kèm (chữ ký được lưu trữ trong kho lưu trữ) khớp với khoá đó.

Quá trình khởi động cũng sẽ tạo gradle/verification-keyring.keys chứa các khoá PGP công khai mà bản dựng của bạn sử dụng. Kiểm tra cả hai tệp này vào hệ thống theo dõi phiên bản. Mọi thay đổi trong tương lai sửa đổi verification-metadata.xml hoặc verification-keyring.keys đều phải được xem xét kỹ lưỡng.

Xoá phiên bản khỏi khoá đáng tin cậy

Khoá ký hiếm khi thay đổi giữa các bản phát hành của thư viện. Dữ liệu được tạo trong tệp gradle/verification-metadata.xml chứa thông tin chi tiết về phiên bản, nghĩa là bạn cần thêm lại thông tin chính cho từng phiên bản phần phụ thuộc mới.

Để tránh điều này và chỉ định rằng khoá áp dụng cho tất cả phiên bản của thư viện, hãy xoá thông số kỹ thuật phiên bản.

Trong trình chỉnh sửa Android Studio, hãy sử dụng Edit > Find > Replace... (Chỉnh sửa > Tìm > Thay thế…) bằng biểu thức chính quy để thay thế tất cả thông số kỹ thuật phiên bản cho các khoá đáng tin cậy.

  • từ: <trusted-key(.*) version=\".*\"/>
  • đến: <trusted-key$1/>

Đồng bộ hoá Android Studio

Cho đến nay, bản dựng dòng lệnh của bạn hoạt động, nhưng nếu cố gắng đồng bộ hoá trong Android Studio, bạn sẽ thấy các lỗi như

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 muốn tải các nguồn Gradle xuống (cùng với các nguồn và tài liệu khác). Cách dễ nhất để khắc phục vấn đề này là tin tưởng tất cả nguồn và javadoc. Thêm <trusted-artifacts> trong 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>

Giờ đây, bản dựng của bạn sẽ hoạt động đúng cách từ dòng lệnh và Android Studio.