หมวดหมู่ OWASP: MASVS-PLATFORM: การโต้ตอบกับแพลตฟอร์ม
ภาพรวม
ตัวรับการออกอากาศที่ติดตั้งใช้งานอย่างไม่ถูกต้องอาจทำให้ผู้โจมตีส่งความตั้งใจที่เป็นอันตรายเพื่อทำให้แอปพลิเคชันที่มีช่องโหว่ดำเนินการซึ่งไม่ได้มีไว้สำหรับผู้เรียกภายนอก
โดยทั่วไปแล้วช่องโหว่หมายถึงกรณีที่มีการส่งออกตัวรับการออกอากาศโดยไม่ตั้งใจ โดยการตั้งค่า android:exported="true"
ใน AndroidManifest หรือสร้างตัวรับการออกอากาศแบบเป็นโปรแกรม ซึ่งทำให้ตัวรับเป็นแบบสาธารณะโดยค่าเริ่มต้�� หากตัวรับไม่มีตัวกรอง Intent ค่าเริ่มต้นจะเป็น "false"
แต่หากตัวรับมีตัวกรอง Intent อย่างน้อย 1 รายการ ค่าเริ่มต้นของ android:exported จะเป็น "true"
ผู้รับการออกอากาศที่ส่งออกโดยเจตนาโดยไม่มีการควบคุมการเข้าถึงที่เหมาะสมอาจถูกละเมิดได้หากนักพัฒนาแอปไม่ได้ตั้งใจให้แอปพลิเคชันทั้งหมดเรียกใช้
ผลกระทบ
ผู้โจมตีอาจใช้ตัวรับการออกอากาศที่ติดตั้งใช้งานอย่างไม่ปลอดภัยเพื่อรับสิทธิ์เข้าถึงที่ไม่ได้รับอนุญาตเพื่อดําเนินการในแอปพลิเคชันซึ่งนักพัฒนาแอปไม่ได้ตั้งใจที่จะเปิดเผยต่อบุคคลที่สาม
การลดปัญหา
หลีกเลี่ยงปัญหาโดยสิ้นเชิง
หากต้องการแก้ไขปัญหานี้อย่างสมบูรณ์ ให้ตั้งค่า exported
เป็น false
โดยทำดังนี้
<receiver android:name=".MyReceiver" android:exported="false">
<intent-filter>
<action android:name="com.example.myapp.MY_ACTION" />
</intent-filter>
</receiver>
ใช้การเรียกและการรับสายกลับ
ในกรณีที่คุณใช้ตัวรับการออกอากาศเพื่อวัตถุประสงค์ภายในแอป (เช่น การแจ้งเตือนเมื่อเหตุการณ์เสร็จสมบูรณ์) คุณสามารถจัดโครงสร้างโค้ดใหม่เพื่อส่งการเรียกกลับที่จะทริกเกอร์หลังจากเหตุการณ์เสร็จสมบูรณ์แทน
Listener เหตุการณ์เสร็จสมบูรณ์
Kotlin
interface EventCompletionListener {
fun onEventComplete(data: String)
}
Java
public interface EventCompletionListener {
public void onEventComplete(String data);
}
งานที่มีความปลอดภัย
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");
}
}
}
กิจกรรมหลัก
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
// ...
}
}
รักษาความปลอดภัยให้กับ Broadcast Receiver ด้วยสิทธิ์
ลงทะเบียนผู้รับแบบไดนามิกสําหรับการออกอากาศที่ได้รับการคุ้มครองเท่านั้น (การออกอากาศที่มีเพียงแอปพลิเคชันระดับระบบเท่านั้นที่ส่งได้) หรือมีสิทธิ์ระดับลายเซ็นที่ประกาศด้วยตนเอง
แหล่งข้อมูล
- องค์ประกอบตัวรับที่ส่งออก
- เอกสารประกอบเกี่ยวกับสิทธิ์ของผู้รับการออกอากาศ
- Intent การส่งข้อมูลแบบมีการป้องกัน