Broadcast Receiver ที่ไม่ปลอดภัย

หมวดหมู่ 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 ด้วยสิทธิ์

ลงทะเบียนผู้รับแบบไดนามิกสําหรับการออกอากาศที่ได้รับการคุ้มครองเท่านั้น (การออกอากาศที่มีเพียงแอปพลิเคชันระดับระบบเท่านั้นที่ส่งได้) หรือมีสิทธิ์ระดับลายเซ็นที่ประกาศด้วยตนเอง

แหล่งข้อมูล