Ý định đang chờ xử lý

Danh mục OWASP: MASVS-PLATFORM: Tương tác với nền tảng

Tổng quan

PendingIntent là mã tham chiếu đến mã thông báo do hệ thống duy trì. Ứng dụng A có thể chuyển một PendingIntent sang ứng dụng B để cho phép ứng dụng B thực thi các thao tác định sẵn thay cho ứng dụng A; bất kể ứng dụng A có còn hoạt động hay không.

Rủi ro: Ý định đang chờ xử lý có thể thay đổi

Một PendingIntent có thể thay đổi, nghĩa là ứng dụng B có thể cập nhật ý định bên trong chỉ định hành động theo logic đã mô tả trong tài liệu fillIn(). Nói cách khác, một ứng dụng độc hại có thể sửa đổi các trường chưa được điền của PendingIntent. Các trường này có thể cho phép truy cập vào các thành phần không được xuất của ứng dụng dễ bị tấn công.

Tác động

Mức độ tác động của lỗ hổng bảo mật này sẽ khác nhau tuỳ thuộc vào việc triển khai chức năng chưa xuất được nhắm mục tiêu của ứng dụng.

Giải pháp giảm thiểu

Chung

Hãy đảm bảo bạn đã thiết lập hành động, thành phần và gói để tránh các lỗ hổng bảo mật nghiêm trọng nhất:

Kotlin

val intent = Intent(intentAction)

// Or other component setting APIs e.g. setComponent, setClass
intent.setClassName(packageName, className)

PendingIntent pendingIntent =
    PendingIntent.getActivity(
        context,
        /* requestCode = */ 0,
        intent, /* flags = */ PendingIntent.FLAG_IMMUTABLE
    )

Java

Intent intent = new Intent(intentAction);

// Or other component setting APIs e.g. setComponent, setClass
intent.setClassName(packageName, className);

PendingIntent pendingIntent =
        PendingIntent.getActivity(
            getContext(),
            /* requestCode= */ 0,
            intent, /* flags= */ 0);

Cờ KHÔNG THỂ THAY ĐỔI

Nếu ứng dụng của bạn dành cho Android 6 (API cấp độ 23) trở lên, hãy chỉ định khả năng thay đổi. Ví dụ: bạn có thể thực hiện việc này bằng cách sử dụng FLAG_IMMUTABLE để ngăn ứng dụng độc hại điền vào các trường chưa được điền:

Kotlin

val pendingIntent =
    PendingIntent.getActivity(
        context,
        /* requestCode = */ 0,
        Intent(intentAction),
        PendingIntent.FLAG_IMMUTABLE)

Java

PendingIntent pendingIntent =
        PendingIntent.getActivity(
            getContext(),
            /* requestCode= */ 0,
            new Intent(intentAction),
            PendingIntent.FLAG_IMMUTABLE);

Trên Android 11 (API cấp độ 30) trở lên, bạn phải chỉ định những trường cần thay đổi để giảm thiểu các lỗ hổng bảo mật vô tình thuộc loại này.

Tài nguyên


Rủi ro: Phát lại ý định đang chờ xử lý

Bạn có thể phát lại một PendingIntent trừ phi đã đặt cờ FLAG_ONE_SHOT. Bạn cần phải sử dụng cờ FLAG_ONE_SHOT để tránh các cuộc tấn công phát lại (thực hiện các hành động không nên lặp lại).

Tác động

Mức độ tác động của lỗ hổng bảo mật này sẽ khác nhau tuỳ thuộc vào việc triển khai quá trình kết thúc nhận ý định. Một ứng dụng độc hại khai thác một PendingIntent được tạo mà không đặt cờ FLAG_ONE_SHOT có thể thu thập và dùng lại ý định đó để lặp lại các hành động chỉ có thể thực hiện một lần.

Giải pháp giảm thiểu

Ý định đang chờ xử lý không được kích hoạt nhiều lần nên sử dụng cờ FLAG_ONE_SHOT để tránh bị tấn công phát lại.

Kotlin

val pendingIntent =
      PendingIntent.getActivity(
          context,
          /* requestCode = */ 0,
          Intent(intentAction),
          PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_ONE_SHOT)

Java

PendingIntent pendingIntent =
        PendingIntent.getActivity(
            getContext(),
            /* requestCode= */ 0,
            new Intent(intentAction),
            PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_ONE_SHOT);

Tài nguyên


Tài nguyên