ข้อมูลนี้มีไว้สำหรับนักพัฒนาซอฟต์แวร์ซึ่งมีแอปที่มีช่องโหว่ Intent Redirection
สิ่งที่จะเกิดขึ้น
แอปของคุณอย่างน้อย 1 แอปมีปัญหา Intent Redirection ซึ่งอาจทำให้แอปที่เป็นอันตรายเข้าถึงคอมโพเนนต์แอปหรือไฟล์ส่วนตัวได้ โปรดอ่านขั้นตอนโดยละเอียดด้านล่างเพื่อแก้ปัญหาที่เกิดขึ้นในแอป เราจะนำแอปที่มีช่องโหว่ด้านความปลอดภัยที่ไม่มีการแก้ไขออกจาก Google Play หลังพ้นกำหนดเวลาที่แสดงใน Play Console
ต้องดำเนินการ
- ลงชื่อเข้าใช้ Play Console และไปที่ส่วนการแจ้งเตือนเพื่อดูแอปที่ได้รับผลกระทบและกำหนดเวลาในการแก้ไขปัญหาเหล่านี้
- อัปเดตแอปที่ได้รับผลกระทบโดยทำตามขั้นตอนที่ไฮไลต์ไว้ด้านล่าง
- ส่งเวอร์ชันที่อัปเดตของแอปที่ได้รับผลกระทบ
แอปของคุณจะได้รับการตรวจสอบอีกครั้งเมื่อมีการส่งใหม่ ขั้นตอนนี้อาจใช้เวลาหลายชั่วโมง หากแอปผ่านการตรวจสอบและเผยแพร่เรียบร้อยแล้ว คุณก็ไม่ต้องดำเนินการใดๆ เพิ่มเติม หากแอปไม่ผ่านการตรวจสอบ จะไม่มีการเผยแพร่แอปเวอร์ชันใหม่และคุณจะได้รับการแจ้งเตือนทางอีเมล
รายละเอียดเพิ่มเติม
การใช้ Intent ที่ไม่น่าเชื่อถือเพื่อเปิดคอมโพเนนต์ (เช่น การเรียกใช้ startActivity) หรือเพื่อแสดงข้อมูล (เช่น การเรียกใช้ setResult) เป็นอันตรายและอาจทำให้แอปที่เป็นอันตรายก่อให้เกิดปัญหาต่อไปนี้ได้
- ขโมยไฟล์ที่มีความละเอียดอ่อนหรือข้อมูลของระบบ (เช่น ข้อความ SMS) จากแอป
- เปิดคอมโพเนนต์ส่วนตัวของแอปด้วยอาร์กิวเมนต์ที่เป็นอันตราย
แอปของคุณต้องไม่เรียกใช้ startActivity, startService, sendBroadcast หรือ setResult ใน Intent ที่ไม่น่าเชื่อถือโดยไม่ได้ตรวจสอบความถูกต้องหรือล้าง Intent เหล่านี้
เราขอแนะนำให้คุณป้องกันช่องโหว่นี้ด้วยวิธีใดวิธีหนึ่งต่อไปนี้
ตัวเลือกที่ 1: ทำคอมโพเนนต์ของแอปที่ได้รับผลกระทบซึ่งมีการเปลี่ยนเส้นทาง Intent ที่ดึงข้อมูลมาให้เป็นแบบส่วนตัว
หากคอมโพเนนต์ของแอปที่ได้รับผลกระทบไม่จำเป็นต้องรับ Intent จากแอปอื่นๆ คุณก็ทำให้คอมโพเนนต์ของแอปนั้นเป็นแบบส่วนตัวได้โดยการตั้งค่า android:exported="false" ในไฟล์ Manifest
ตัวเลือกที่ 2: ตรวจสอบว่า Intent ที่ดึงข้อมูลมานั้นมาจากแหล่งที่เชื่อถือได้
คุณตรวจสอบได้ว่ากิจกรรมที่เรียกใช้งานนั้นเชื่อถือได้โดยใช้เมธอดอย่างเช่น getCallingActivity เช่น
// ตรวจสอบว่ากิจกรรมที่เรียกใช้งานนั้นมาจากแพ็กเกจที่เชื่อถือได้
if (getCallingActivity().getPackageName().equals(“known”)) {
Intent intent = getIntent();
// ดึงข้อมูล Intent ที่ฝังอยู่
Intent forward = (Intent) intent.getParcelableExtra(“key”);
// เปลี่ยนเส้นทาง Intent ที่ฝังอยู่
startActivity(forward);
}
หมายเหตุ:
- การตรวจสอบว่า getCallingActivity() แสดงผลค่าที่ไม่ใช่ค่า Null หรือไม่นั้นไม่เพียงพอต่อการป้องกันช่องโหว่ แอปที่เป็นอันตรายอาจให้ค่า Null สำหรับฟังก์ชันนี้
- ในกรณีของ SMS Retriever Auth ของบริการ Google Play การปกป้อง Broadcast Receiver ด้วย SEND_PERMISSION จะช่วยให้มั่นใจว่า Intent มาจากบริการ Google Play
ตัวเลือกที่ 3: ตรวจสอบว่า Intent ที่จะเปลี่ยนเส้นทางนั้นไม่เป็นอันตราย
คุณควรตรวจสอบว่า Intent ที่มีการเปลี่ยนเส้นทางดังกล่าวเป็นไปตามเงื่อนไขต่อไปนี้
- จะไม่มีการส่งไปยังคอมโพเนนต์แบบส่วนตัวของแอปใดๆ และ
- จะไม่มีการส่งไปยังคอมโพเนนต์ของแอปภายนอก หากการเปลี่ยนเส้นทางมีไว้เพื่อกำหนดเป้าหมายเป็นแอปภายนอก ให้ตรวจสอบว่า Intent จะไม่ให้สิทธิ์ URI แก่ผู้ให้บริการเนื้อหาส่วนตัวรายใดรายหนึ่งของแอปหรือข้อมูลของระบบ
แอปจะตรวจสอบได้ว่าจะใช้คอมโพเนนต์ใดในการจัดการ Intent ก่อนที่จะเปลี่ยนเส้นทางโดยใช้เมธอดอย่างเช่น resolveActivity เช่น
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);
}
แอปจะตรวจสอบได้ว่าจะให้ Intent ให้สิทธิ์ URI หรือไม่โดยใช้เมธอดอย่างเช่น getFlags เช่น
// 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);
}
แอปยังนำการให้สิทธิ์ URI ออกโดยใช้ removeFlags ได้ด้วย เช่น
// 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);
ทำความเข้าใจการแจ้งเตือนและเลือกตัวเลือกการป้องกัน
การแจ้งเตือนของ Play Console จะรายงานเมื่อแอปเรียกใช้ startActivity, startActivityForResult, startService, sendBroadcast หรือ setResult โดยใช้ Intent ที่ไม่น่าเชื่อถือ หากต้องการทราบว่าตัวเลือกการป้องกันใดที่เหมาะสมที่สุด ให้ย้อนกลับไปดูที่ Caller ของเมธอดเพื่อดูว่า Intent ที่ไม่น่าเชื่อถือนั้นมีต้นทางมาจากที่ไหน เช่น สำหรับตัวเลือกที่ 1 ให้ย้อนกลับไปเพื่อเลือกคอมโพเนนต์ที่จะทำให้เป็นแบบส่วนตัว
เราพร้อมช่วยเหลือคุณ
หากมีคำถามทางเทคนิคเกี่ยวกับช่องโหว่ดังกล่าว คุณโพสต์ถามได้ที่ Stack Overflow และใช้แท็ก “android-security” หากต้องการคำชี้แจงเกี่ยวกับขั้นตอนที่ต้องดำเนินการเพื่อแก้ไขปัญหานี้ โปรดติดต่อทีมสนับสนุนนักพัฒนาซอฟต์แวร์