Broadcast receiver không an toàn
Sử dụng bộ sưu tập để sắp xếp ngăn nắp các trang
Lưu và phân loại nội dung dựa trên lựa chọn ưu tiên của bạn.
Danh mục OWASP: MASVS-PLATFORM: Tương tác với nền tảng
Tổng quan
Việc triển khai không đúng cách trình thu nhận thông báo truyền tin có thể cho phép kẻ tấn công gửi một ý định độc hại để khiến ứng dụng dễ bị tấn công thực hiện các hành động không dành cho phương thức gọi bên ngoài.
Lỗ hổng này thường đề cập đến các trường hợp mà broadcast receiver được xuất không chủ ý, bằng cách đặt android:exported="true"
trong AndroidManifest hoặc bằng cách tạo broadcast receiver theo phương thức lập trình, khiến receiver trở thành công khai theo mặc định. Nếu broadcast receiver không chứa bộ lọc ý định nào, thì giá trị mặc định sẽ là "false"
, nhưng nếu broadcast receiver chứa ít nhất một bộ lọc ý định, thì giá trị mặc định của android:exported sẽ là "true"
.
Các trình thu nhận thông báo truyền tin được xuất có chủ ý mà không có quyền kiểm soát truy cập thích hợp có thể bị lợi dụng nếu nhà phát triển không có ý định cho phép tất cả ứng dụng gọi trình thu nhận đó.
Tác động
Kẻ tấn công có thể lợi dụng các broadcast receiver được triển khai không an toàn để giành quyền truy cập trái phép nhằm thực thi hành vi trong ứng dụng mà nhà phát triển không có ý định tiết lộ cho bên thứ ba.
Giải pháp giảm thiểu
Tránh hoàn toàn vấn đề
Để giải quyết hoàn toàn vấn đề này, hãy đặt exported
thành false
:
<receiver android:name=".MyReceiver" android:exported="false">
<intent-filter>
<action android:name="com.example.myapp.MY_ACTION" />
</intent-filter>
</receiver>
Sử dụng lệnh gọi và lệnh gọi lại
Trong trường hợp bạn đã sử dụng broadcast receiver cho các mục đích nội bộ của ứng dụng (ví dụ: thông báo hoàn tất sự kiện), bạn có thể tái cấu trúc mã để truyền lệnh gọi lại sẽ kích hoạt sau khi sự kiện hoàn tất.
Trình nghe hoàn tất sự kiện
Kotlin
interface EventCompletionListener {
fun onEventComplete(data: String)
}
Java
public interface EventCompletionListener {
public void onEventComplete(String data);
}
Bảo mật tác vụ
Kotlin
class SecureTask(private val listener: EventCompletionListener?) {
fun executeTask() {
// Do some work...
// Notify that the event is complete
listener?.onEventComplete("Some secure data")
}
}
Java
public class SecureTask {
final private EventCompletionListener listener;
public SecureTask(EventCompletionListener listener) {
this.listener = listener;
}
public void executeTask() {
// Do some work...
// Notify that the event is complete
if (listener != null) {
listener.onEventComplete("Some secure data");
}
}
}
Hoạt động chính
Kotlin
class MainActivity : AppCompatActivity(), EventCompletionListener {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val secureTask = SecureTask(this)
secureTask.executeTask()
}
override fun onEventComplete(data: String) {
// Handle event completion securely
// ...
}
}
Java
public class MainActivity extends AppCompatActivity implements EventCompletionListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SecureTask secureTask = new SecureTask(this);
secureTask.executeTask();
}
@Override
public void onEventComplete(String data) {
// Handle event completion securely
// ...
}
}
Bảo mật broadcast receiver bằng quyền
Chỉ đăng ký broadcast receiver động cho thông báo truyền tin được bảo vệ (thông báo truyền tin mà chỉ các ứng dụng cấp hệ thống mới có thể gửi) hoặc với quyền cấp chữ ký tự khai báo.
Tài nguyên
Nội dung và mã mẫu trên trang này phải tuân thủ các giấy phép như mô tả trong phần Giấy phép nội dung. Java và OpenJDK là nhãn hiệu hoặc nhãn hiệu đã đăng ký của Oracle và/hoặc đơn vị liên kết của Oracle.
Cập nhật lần gần đây nhất: 2025-07-26 UTC.
[[["Dễ hiểu","easyToUnderstand","thumb-up"],["Giúp tôi giải quyết được vấn đề","solvedMyProblem","thumb-up"],["Khác","otherUp","thumb-up"]],[["Thiếu thông tin tôi cần","missingTheInformationINeed","thumb-down"],["Quá phức tạp/quá nhiều bước","tooComplicatedTooManySteps","thumb-down"],["Đã lỗi thời","outOfDate","thumb-down"],["Vấn đề về bản dịch","translationIssue","thumb-down"],["Vấn đề về mẫu/mã","samplesCodeIssue","thumb-down"],["Khác","otherDown","thumb-down"]],["Cập nhật lần gần đây nhất: 2025-07-26 UTC."],[],[],null,["# Insecure broadcast receivers\n\n\u003cbr /\u003e\n\n**OWASP category:** [MASVS-PLATFORM: Platform Interaction](https://mas.owasp.org/MASVS/09-MASVS-PLATFORM)\n\nOverview\n--------\n\nImproperly implemented broadcast receivers can allow an attacker to send a\nmalicious intent to make the vulnerable application perform actions which are\nnot intended for external callers.\n\nThe vulnerability generally refers to instances where the broadcast receiver is\nunintentionally exported, either by setting [`android:exported=\"true\"`](/guide/topics/manifest/receiver-element#exported) in\nthe AndroidManifest or by creating a broadcast receiver programmatically which\nmakes the receiver public by default. If the receiver doesn't contain any intent\nfilters the default value is `\"false\"` but if the receiver contains at least one\nintent filter the default value of android:exported is `\"true\"`.\n\nIntentionally exported broadcast receivers without proper access control can be\nabused if the developer did not intend for it to be called by all applications.\n\nImpact\n------\n\nInsecurely implemented broadcast receivers can be abused by an attacker to gain\nunauthorized access to execute behavior in the application that the developer\ndid not mean to expose to third parties.\n\nMitigations\n-----------\n\n### Avoid the problem entirely\n\nTo resolve the dilemma entirely, set `exported` to `false`: \n\n \u003creceiver android:name=\".MyReceiver\" android:exported=\"false\"\u003e\n \u003cintent-filter\u003e\n \u003caction android:name=\"com.example.myapp.MY_ACTION\" /\u003e\n \u003c/intent-filter\u003e\n \u003c/receiver\u003e\n\n### Use calls and callbacks\n\nIn the case you used broadcast receivers for internal app purposes (ie. event\ncompletion notification), you can restructure your code to pass a callback that\nwould fire after event completion instead.\n\n###### Event completion listener\n\n### Kotlin\n\n interface EventCompletionListener {\n fun onEventComplete(data: String)\n }\n\n### Java\n\n public interface EventCompletionListener {\n public void onEventComplete(String data);\n }\n\n###### Secure task\n\n### Kotlin\n\n class SecureTask(private val listener: EventCompletionListener?) {\n fun executeTask() {\n // Do some work...\n\n // Notify that the event is complete\n listener?.onEventComplete(\"Some secure data\")\n }\n }\n\n### Java\n\n public class SecureTask {\n\n final private EventCompletionListener listener;\n\n public SecureTask(EventCompletionListener listener) {\n this.listener = listener;\n }\n\n public void executeTask() {\n // Do some work...\n\n // Notify that the event is complete\n if (listener != null) {\n listener.onEventComplete(\"Some secure data\");\n }\n }\n }\n\n###### Main activity\n\n### Kotlin\n\n class MainActivity : AppCompatActivity(), EventCompletionListener {\n override fun onCreate(savedInstanceState: Bundle?) {\n super.onCreate(savedInstanceState)\n setContentView(R.layout.activity_main)\n\n val secureTask = SecureTask(this)\n secureTask.executeTask()\n }\n\n override fun onEventComplete(data: String) {\n // Handle event completion securely\n // ...\n }\n }\n\n### Java\n\n public class MainActivity extends AppCompatActivity implements EventCompletionListener {\n\n @Override\n protected void onCreate(Bundle savedInstanceState) {\n super.onCreate(savedInstanceState);\n setContentView(R.layout.activity_main);\n\n SecureTask secureTask = new SecureTask(this);\n secureTask.executeTask();\n }\n\n @Override\n public void onEventComplete(String data) {\n // Handle event completion securely\n // ...\n }\n }\n\n### Secure broadcast receivers with permissions\n\nOnly register dynamic receivers for [protected broadcasts](/about/versions/12/reference/broadcast-intents-31) (broadcasts that\nonly system level applications can send) or with [self-declared signature level\npermissions](/guide/topics/manifest/permission-element#plevel).\n\nResources\n---------\n\n- [Exported Receiver Elements](/guide/topics/manifest/receiver-element#exported)\n- [Broadcast Receiver Permissions documentation](/guide/components/broadcasts#receiving-broadcasts-permissions)\n- [Protected Broadcast Intents](/about/versions/12/reference/broadcast-intents-31)"]]