Khắc phục lỗ hổng Intent Redirection

Thông tin này dành cho các nhà phát triển có ứng dụng chứa lỗ hổng Intent Redirection.

Điều gì đang xảy ra

Một hoặc nhiều ứng dụng của bạn gặp vấn đề về lỗ hổng Intent Redirection. Lỗ hổng này có thể cho phép các ứng dụng độc hại truy cập các thành phần hoặc tệp riêng tư của ứng dụng. Vui lòng xem lại các bước chi tiết bên dưới để khắc phục vấn đề với ứng dụng của bạn. Sau thời hạn hiển thị trong Play Console, chúng tôi sẽ xóa mọi ứng dụng có lỗ hổng bảo mật chưa được khắc phục khỏi Google Play.

Việc cần làm​

  1. Đăng nhập vào Play Console và chuyển đến mục Cảnh báo để xem những ứng dụng nào đang bị ảnh hưởng và thời hạn giải quyết những vấn đề này.
  2. Cập nhật các ứng dụng bị ảnh hưởng theo các bước nêu bên dưới.
  3. Gửi phiên bản cập nhật của các ứng dụng bị ảnh hưởng.

Sau khi bạn gửi lại, chúng tôi sẽ xem xét lại ứng dụng của bạn. Quá trình này có thể mất vài giờ. Nếu ứng dụng vượt qua quy trình xem xét và được xuất bản thành công thì bạn không cần thực hiện thêm hành động nào. Nếu ứng dụng không vượt qua được quy trình xem xét thì phiên bản ứng dụng mới sẽ không được xuất bản và bạn sẽ nhận được thông báo qua email.

Thông tin chi tiết bổ sung

Việc sử dụng một Intent không tin cậy để chạy một thành phần (ví dụ: bằng cách gọi startActivity) hoặc để trả về dữ liệu (ví dụ: bằng cách gọi setResult) là rất nguy hiểm và có thể khiến ứng dụng độc hại gây ra những vấn đề sau: 

  1. Đánh cắp các tệp nhạy cảm hoặc dữ liệu hệ thống (chẳng hạn như tin nhắn SMS) qua ứng dụng của bạn
  2. Chạy các thành phần riêng tư trong ứng dụng của bạn bằng các đối số bị nhiễm độc.

Quan trọng là ứng dụng của bạn không được gọi startActivity, startService, sendBroadcast hoặc setResult trên các Intent không tin cậy khi chưa xác minh hoặc làm sạch những Intent đó.

Bạn nên ngăn chặn lỗ hổng này theo một trong các cách sau:

Tùy chọn 1: Đặt thành phần ứng dụng bị ảnh hưởng (Intent đã trích xuất bị chuyển hướng khỏi thành phần này) ở chế độ riêng tư.

Nếu thành phần ứng dụng bị ảnh hưởng không cần nhận Intent từ các ứng dụng khác thì bạn có thể đặt thành phần ứng dụng đó ở chế độ riêng tư bằng cách thiết lập android:exported=”false” trong Tệp kê khai.

Tùy chọn 2: Đảm bảo rằng Intent được trích xuất là từ một nguồn đáng tin cậy.

Bạn có thể xác minh rằng Hoạt động gốc là đáng tin cậy bằng các phương thức như getCallingActivity. Ví dụ:

 // kiểm tra xem Hoạt động gốc có bắt nguồn từ gói đáng tin cậy hay không
 if (getCallingActivity().getPackageName().equals(“known”)) {
   Intent intent = getIntent();
   // extract the nested Intent
   Intent forward = (Intent) intent.getParcelableExtra(“key”);
   // redirect the nested Intent
   startActivity(forward);
 }

Lưu ý:

  • Việc kiểm tra xem getCallingActivity() có trả về giá trị rỗng hay không là chưa đủ để ngăn chặn lỗ hổng. Các ứng dụng độc hại có thể cung cấp giá trị rỗng cho hàm này.
  • Trong trường hợp Xác thực Thu thập SMS qua các dịch vụ của Google Play, việc bảo vệ một broadcast receiver bằng SEND_PERMISSION sẽ đảm bảo Intent do Dịch vụ của Google Play cung cấp.

Tùy chọn 3: Đảm bảo rằng Intent được chuyển hướng không gây hại.

Bạn nên xác minh rằng Intent được chuyển hướng

  1. sẽ không được gửi đến thành phần riêng tư nào trong ứng dụng của bạn và
  2. sẽ không được gửi đến thành phần của ứng dụng bên ngoài. Nếu việc chuyển hướng là để nhắm đến ứng dụng bên ngoài, thì hãy đảm bảo Intent sẽ không cấp quyền URI cho một trong những nhà cung cấp nội dung riêng tư của ứng dụng hay dữ liệu hệ thống.

Các ứng dụng có thể kiểm tra xem thành phần nào sẽ được dùng để xử lý Intent trước khi chuyển hướng Intent đó bằng các phương thức như resolveActivity. Ví dụ:

 Intent intent = getIntent();
 // extract the nested Intent
 Intent forward = (Intent) intent.getParcelableExtra(“key”);
 // get the component name
 ComponentName name = forward.resolveActivity(getPackageManager());
 // check that the package name and class name are as intended
 if (name.getPackageName().equals(“safe_package”) &&
     name.getClassName().equals(“safe_class”)) {
   // redirect the nested Intent
   startActivity(forward);
 }

Các ứng dụng có thể kiểm tra xem một Intent có cấp quyền URI hay không bằng các phương thức như getFlags. Ví dụ:

 // extract the nested Intent
 Intent forward = (Intent) intent.getParcelableExtra(“key”);
 // get the flags
 int flags = forward.getFlags();
 // check that the nested intent does not grant URI permissions
 if ((flags & Intent.FLAG_GRANT_READ_URI_PERMISSION == 0) &&
     (flags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION == 0)) {
   // redirect the nested Intent
   startActivity(forward);
 }

Các ứng dụng cũng có thể dùng removeFlags để xóa quyền URI đã cấp. Ví dụ:

 // untrusted Intent
 Intent intent = getIntent();
 // remove the grant URI permissions in the untrusted Intent
 intent.removeFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
 intent.removeFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
 // pass the untrusted Intent
 setResult(intent);

Hiểu về cảnh báo và chọn phương thức ngăn chặn 

Chức năng cảnh báo của Play Console giúp báo cáo nơi ứng dụng của bạn gọi startActivity, startActivityForResult, startService, sendBroadcast hoặc setResult qua một Intent không tin cậy. Để nắm rõ liệu phương thức ngăn chặn nào là thích hợp nhất, hãy truy vết ngược lại và tìm hiểu phương thức gọi để tìm ra nguồn gốc của Intent không tin cậy đó. Ví dụ: Đối với Tùy chọn 1, hãy truy vết ngược lại để xác định nên đặt chế độ riêng tư cho thành phần nào.

Chúng tôi sẵn lòng trợ giúp

Nếu bạn có câu hỏi kỹ thuật về lỗ hổng bảo mật này, bạn có thể đăng lên Stack Overflow và gắn thẻ "android-security". Để hiểu rõ hơn về các bước cần thực hiện nhằm giải quyết vấn đề này, bạn có thể liên hệ với nhóm hỗ trợ nhà phát triển của chúng tôi.

Thông tin này có hữu ích không?

Chúng tôi có thể cải thiện trang này bằng cách nào?
false
Trình đơn chính
15389018580068874183
true
Tìm kiếm trong Trung tâm trợ giúp
true
true
true
true
true
5016068
false
false