การแก้ไขช่องโหว่ Intent Redirection

ข้อมูลนี้มีไว้สำหรับนักพัฒนาซอฟต์แวร์ซึ่งมีแอปที่มีช่องโหว่ Intent Redirection

สิ่งที่จะเกิดขึ้น

แอปของคุณอย่างน้อย 1 แอปมีปัญหา Intent Redirection ซึ่งอาจทำให้แอปที่เป็นอันตรายเข้าถึงคอมโพเนนต์แอปหรือไฟล์ส่วนตัวได้ โปรดอ่านขั้นตอนโดยละเอียดด้านล่างเพื่อแก้ปัญหาที่เกิดขึ้นในแอป เราจะนำแอปที่มีช่องโหว่ด้านความปลอดภัยที่ไม่มีการแก้ไขออกจาก Google Play หลังพ้นกำหนดเวลาที่แสดงใน Play Console

ต้องดำเนินการ​

  1. ลงชื่อเข้าใช้ Play Console และไปที่ส่วนการแจ้งเตือนเพื่อดูแอปที่ได้รับผลกระทบและกำหนดเวลาในการแก้ไขปัญหาเหล่านี้
  2. อัปเดตแอปที่ได้รับผลกระทบโดยทำตามขั้นตอนที่ไฮไลต์ไว้ด้านล่าง
  3. ส่งเวอร์ชันที่อัปเดตของแอปที่ได้รับผลกระทบ

แอปของคุณจะได้รับการตรวจสอบอีกครั้งเมื่อมีการส่งใหม่ ขั้นตอนนี้อาจใช้เวลาหลายชั่วโมง หากแอปผ่านการตรวจสอบและเผยแพร่เรียบร้อยแล้ว คุณก็ไม่ต้องดำเนินการใดๆ เพิ่มเติม หากแอปไม่ผ่านการตรวจสอบ จะไม่มีการเผยแพร่แอปเวอร์ชันใหม่และคุณจะได้รับการแจ้งเตือนทางอีเมล

รายละเอียดเพิ่มเติม

การใช้ Intent ที่ไม่น่าเชื่อถือเพื่อเปิดคอมโพเนนต์ (เช่น การเรียกใช้ startActivity) หรือเพื่อแสดงข้อมูล (เช่น การเรียกใช้ setResult) เป็นอันตรายและอาจทำให้แอปที่เป็นอันตรายก่อให้เกิดปัญหาต่อไปนี้ได้ 

  1. ขโมยไฟล์ที่มีความละเอียดอ่อนหรือข้อมูลของระบบ (เช่น ข้อความ SMS) จากแอป
  2. เปิดคอมโพเนนต์ส่วนตัวของแอปด้วยอาร์กิวเมนต์ที่เป็นอันตราย

แอปของคุณต้องไม่เรียกใช้ 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 ที่มีการเปลี่ยนเส้นทางดังกล่าวเป็นไปตามเงื่อนไขต่อไปนี้

  1. จะไม่มีการส่งไปยังคอมโพเนนต์แบบส่วนตัวของแอปใดๆ และ
  2. จะไม่มีการส่งไปยังคอมโพเนนต์ของแอปภายนอก หากการเปลี่ยนเส้นทางมีไว้เพื่อกำหนดเป้าหมายเป็นแอปภายนอก ให้ตรวจสอบว่า 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” หากต้องการคำชี้แจงเกี่ยวกับขั้นตอนที่ต้องดำเนินการเพื่อแก้ไขปัญหานี้ โปรดติดต่อทีมสนับสนุนนักพัฒนาซอฟต์แวร์

ข้อมูลนี้มีประโยชน์ไหม

เราจะปรับปรุงได้อย่างไร
false
เมนูหลัก
16838249374202817066
true
ค้นหาศูนย์ช่วยเหลือ
true
true
true
true
true
5016068
false
false