แพลตฟอร์ม Android ใช้ประโยชน์จากการป้องกันแบบผู้ใช้ Linux เพื่อระบุและแยกทรัพยากรของแอพ สิ่งนี้แยกแอพออกจากกันและปกป้องแอพและระบบจากแอพที่เป็นอันตราย ในการดำเนินการนี้ Android จะกำหนด ID ผู้ใช้ (UID) ที่ไม่ซ้ำกันให้กับแอปพลิเคชัน Android แต่ละแอปและเรียกใช้ในกระบวนการของตัวเอง
Android ใช้ UID เพื่อตั้งค่า Application Sandbox ระดับเคอร์เนล เคอร์เนลบังคับใช้การรักษาความปลอดภัยระหว่างแอพและระบบที่ระดับกระบวนการผ่านสิ่งอำนวยความสะดวกมาตรฐานของ Linux เช่น ID ผู้ใช้และกลุ่มที่กำหนดให้กับแอพ ตามค่าเริ่มต้น แอปจะไม่สามารถโต้ตอบกันและเข้าถึงระบบปฏิบัติการได้จำกัด หากแอป A พยายามทำอะไรที่เป็นอันตราย เช่น อ่านข้อมูลของแอปพลิเคชัน B หรือโทรออกโดยไม่ได้รับอนุญาต แอปดังกล่าวจะป้องกันไม่ให้ทำเช่นนั้นเนื่องจากไม่มีสิทธิ์ผู้ใช้เริ่มต้นที่เหมาะสม แซนด์บ็อกซ์นั้นเรียบง่าย ตรวจสอบได้ และอิงตามการแยกกระบวนการและการอนุญาตไฟล์ของผู้ใช้แบบ UNIX ที่มีอายุหลายสิบปี
เนื่องจากแซนด์บ็อกซ์แอปพลิเคชันอยู่ในเคอร์เนล โมเดลความปลอดภัยนี้จึงขยายไปยังทั้งแอปพลิเคชันโค้ดเนทีฟและระบบปฏิบัติการ ซอฟต์แวร์ทั้งหมดที่อยู่เหนือเคอร์เนล เช่น ไลบรารีระบบปฏิบัติการ เฟรมเวิร์กของแอปพลิเคชัน รันไทม์ของแอปพลิเคชัน และแอปพลิเคชันทั้งหมด ทำงานภายใน Application Sandbox ในบางแพลตฟอร์ม นักพัฒนาจะถูกจำกัดด้วยเฟรมเวิร์กการพัฒนา ชุดของ API หรือภาษาที่เฉพาะเจาะจง บน Android ไม่มีข้อจำกัดในการเขียนแอปพลิเคชันที่จำเป็นสำหรับการบังคับใช้ความปลอดภัย ในแง่นี้ โค้ดเนทีฟจะถูกแซนด์บ็อกซ์เหมือนกับโค้ดที่ตีความ
ความคุ้มครอง
โดยทั่วไป ในการแยกตัวออกจาก Application Sandbox ในอุปกรณ์ที่กำหนดค่าอย่างเหมาะสม ผู้ใช้ต้องประนีประนอมความปลอดภัยของเคอร์เนลลินุกซ์ อย่างไรก็ตาม เช่นเดียวกับคุณลักษณะด้านความปลอดภัยอื่นๆ การป้องกันส่วนบุคคลที่บังคับใช้แซนด์บ็อกซ์ของแอปพลิเคชันนั้นไม่สามารถคงกระพันได้ ดังนั้นการป้องกันในเชิงลึกจึงเป็นสิ่งสำคัญในการป้องกันไม่ให้มีช่องโหว่เดียวที่นำไปสู่การประนีประนอมของระบบปฏิบัติการหรือแอปอื่นๆ
Android ใช้การป้องกันหลายประการในการบังคับใช้แซนด์บ็อกซ์ของแอปพลิเคชัน มีการบังคับใช้การบังคับใช้เหล่านี้เมื่อเวลาผ่านไปและได้เสริมความแข็งแกร่งให้กับแซนด์บ็อกซ์การควบคุมการเข้าถึงตามอำเภอใจ (DAC) ที่ใช้ UID ดั้งเดิมอย่างมาก รุ่นก่อนหน้าของ Android มีการป้องกันดังต่อไปนี้:
- ใน Android 5.0 SELinux ได้จัดเตรียมการแยกการควบคุมการเข้าถึง (MAC) ที่จำเป็นระหว่างระบบและแอป อย่างไรก็ตาม แอปของบุคคลที่สามทั้งหมดทำงานภายในบริบท SELinux เดียวกัน ดังนั้นการแยกระหว่างแอปจึงถูกบังคับใช้โดย UID DAC เป็นหลัก
- ใน Android 6.0 แซนด์บ็อกซ์ SELinux ได้รับการขยายเพื่อแยกแอปออกจากขอบเขตต่อผู้ใช้จริง นอกจากนี้ Android ยังตั้งค่าเริ่มต้นที่ปลอดภัยกว่าสำหรับข้อมูลแอปพลิเคชัน: สำหรับแอปที่มี
targetSdkVersion >= 24
การอนุญาต DAC เริ่มต้นบนโฮมไดร์ของแอปเปลี่ยนจาก 751 เป็น 700 ซึ่งเป็นค่าเริ่มต้นที่ปลอดภัยกว่าสำหรับข้อมูลแอปส่วนตัว (แม้ว่าแอปอาจแทนที่ค่าเริ่มต้นเหล่านี้) . - ใน Android 8.0 แอปทั้งหมดถูกตั้งค่าให้ทำงานด้วยตัวกรอง
seccomp-bpf
ที่จำกัด syscalls ที่แอปได้รับอนุญาตให้ใช้ ซึ่งจะช่วยเสริมความแข็งแกร่งให้กับขอบเขตของแอป/เคอร์เนล - ใน Android 9 แอปที่ไม่ได้รับสิทธิพิเศษทั้งหมดที่มี
targetSdkVersion >= 28
ต้องทำงานในแซนด์บ็อกซ์ SELinux แต่ละรายการ โดยให้ MAC เป็นแบบต่อแอป การป้องกันนี้ช่วยปรับปรุงการแยกแอป ป้องกันการแทนที่ค่าเริ่มต้นที่ปลอดภัย และ (ที่สำคัญที่สุด) ป้องกันไม่ให้แอปเข้าถึงโลกของข้อมูล - ในแอพ Android 10 มีมุมมองดิบที่จำกัดของระบบไฟล์ โดยไม่มีการเข้าถึงเส้นทางโดยตรง เช่น /sdcard/DCIM อย่างไรก็ตาม แอปจะคงสิทธิ์การเข้าถึงแบบ Raw ในเส้นทางเฉพาะแพ็คเกจตามที่ส่งคืนโดยวิธีการที่เกี่ยวข้อง เช่น Context.getExternalFilesDir()
แนวทางการแชร์ไฟล์
การตั้งค่าข้อมูลแอพให้เข้าถึงได้ทั่วโลกนั้นเป็นแนวทางปฏิบัติด้านความปลอดภัยที่ไม่ดี ทุกคนอนุญาตให้เข้าถึงได้ และไม่สามารถจำกัดการเข้าถึงได้เฉพาะผู้รับที่ต้องการเท่านั้น แนวทางปฏิบัตินี้นำไปสู่การเปิดเผยข้อมูลรั่วไหลและเกิดความสับสนกับช่องโหว่รอง และเป็นเป้าหมายโปรดสำหรับมัลแวร์ที่กำหนดเป้าหมายแอปที่มีข้อมูลที่ละเอียดอ่อน (เช่นไคลเอ็นต์อีเมล) ใน Android 9 ขึ้นไป การแชร์ไฟล์ด้วยวิธีนี้จะไม่ได้รับอนุญาตอย่างชัดเจนสำหรับแอปที่มี targetSdkVersion>=28
แทนที่จะทำให้ข้อมูลแอปเข้าถึงได้ทั่วโลก ให้ใช้แนวทางต่อไปนี้เมื่อแชร์ไฟล์:
- หากแอปของคุณต้องการแชร์ไฟล์กับแอปอื่น ให้ใช้ ผู้ให้บริการเนื้อหา ผู้ให้บริการเนื้อหาแบ่งปันข้อมูลด้วยความละเอียดที่เหมาะสมและไม่มีข้อเสียหลายประการของการอนุญาต UNIX ที่เข้าถึงได้ทั่วโลก (สำหรับรายละเอียด โปรดดูที่ ข้อมูลเบื้องต้นเกี่ยวกับผู้ให้บริการเนื้อหา )
- หากแอพของคุณมีไฟล์ที่คนทั้งโลกควรสามารถเข้าถึงได้อย่างแท้จริง (เช่น รูปภาพ) ไฟล์เหล่านั้นจะต้องเป็นไฟล์เฉพาะสื่อ (ภาพถ่าย วิดีโอ และไฟล์เสียงเท่านั้น) และจัดเก็บโดยใช้คลาส MediaStore (สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับวิธีการเพิ่มรายการสื่อ โปรดดู เข้าถึงไฟล์สื่อจากที่จัดเก็บข้อมูลที่แชร์ )
สิทธิ์รันไทม์ของ Storage ควบคุมการเข้าถึงคอลเล็กชันที่พิมพ์อย่างเข้มงวดผ่าน MediaStore สำหรับการเข้าถึงไฟล์ที่พิมพ์ไม่ละเอียด เช่น PDF และคลาส MediaStore.Downloads แอปต้องใช้ Intents เช่น ACTION_OPEN_DOCUMENT
ในการเปิดใช้งาน Android 10 ให้ใช้แอตทริบิวต์รายการ requestLegacyExternalStorage
และปฏิบัติตาม แนวทางปฏิบัติที่ดีที่สุดสำหรับการอนุญาตแอป
- ค่าเริ่มต้นของการตั้งค่าสถานะรายการเป็น
true
สำหรับแอปที่กำหนดเป้าหมายเป็น Android 9 (และต่ำกว่า) - ค่าเริ่มต้นเป็นเท็จสำหรับแอปที่กำหนดเป้าหมายเป็น Android 10 หากต้องการเลือกไม่ใช้มุมมองพื้นที่เก็บข้อมูลที่กรองไว้ชั่วคราวในแอปที่กำหนดเป้าหมายเป็น Android 10 ให้ตั้งค่าสถานะรายการเป็น
true
- ด้วยการใช้สิทธิ์ที่จำกัด โปรแกรมติดตั้งจะอนุญาตแอปที่อนุญาตสำหรับพื้นที่จัดเก็บที่ไม่ใช่แซนด์บ็อกซ์ แอปที่ไม่อนุญาตพิเศษจะถูกแซนด์บ็อกซ์