รายการตรวจสอบการรักษาความปลอดภัย

Android มีฟีเจอร์รักษาความปลอดภัยในตัวที่ช่วยลดความถี่ และผลกระทบของปัญหาด้านความปลอดภัยของแอปพลิเคชันได้อย่างมาก ระบบได้รับการออกแบบมาเพื่อให้คุณ สร้างแอปด้วยสิทธิ์ของระบบและไฟล์เริ่มต้นได้ตามปกติ และ ไม่ต้องตัดสินใจเรื่องความปลอดภัยที่ซับซ้อน

ฟีเจอร์ด้านความปลอดภัยหลักต่อไปนี้จะช่วยคุณสร้างแอปที่ปลอดภัย

  • แซนด์บ็อกซ์แอปพลิเคชัน Android ซึ่งแยกข้อมูลแอปและโค้ดของแอปจากการเรียกใช้ของแอปอื่นๆ
  • เฟรมเวิร์กแอปพลิเคชันที่มีการติดตั้งใช้งานฟังก์ชันความปลอดภัยทั่วไปอย่างเข้มงวด เช่น วิทยาการเข้ารหัส สิทธิ์ และการสื่อสารระหว่างโปรเซส (IPC) ที่ปลอดภัย
  • เทคโนโลยีต่างๆ เช่น Address Space Layout Randomization (ASLR), No-Execute (NX), ProPolice, safe_iop, OpenBSD dlmalloc และ calloc รวมถึง Linux mmap_min_addr เพื่อ ลดความเสี่ยงที่เกี่ยวข้องกับข้อผิดพลาดในการจัดการหน่วยความจำทั่วไป
  • สิทธิ์ที่ผู้ใช้ให้เพื่อจำกัดการเข้าถึงฟีเจอร์ของระบบและข้อมูลผู้ใช้
  • สิทธิ์ที่แอปพลิเคชันกำหนดเพื่อควบคุมข้อมูลแอปพลิเคชันในแต่ละแอป

คุณควรทำความคุ้นเคยกับแนวทางปฏิบัติแนะนำด้านความปลอดภัยของ Android ในหน้านี้ การปฏิบัติตามแนวทางเหล่านี้เป็นนิสัยการเขียนโค้ดทั่วไปจะช่วยให้คุณหลีกเลี่ยง การทำให้เกิดปัญหาด้านความปลอดภัยโดยไม่ตั้งใจ ซึ่งส่งผลเสียต่อผู้ใช้

การตรวจสอบสิทธิ์

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

คุณสามารถปรับปรุงประสบการณ์การตรวจสอบสิทธิ์ของผู้ใช้ได้โดยการผสานรวมแอปกับCredential Manager Credential Manager เป็นไลบรารี Android Jetpack ที่รวมการรองรับ API สำหรับวิธีการตรวจสอบสิทธิ์หลักๆ ส่วนใหญ่ ซึ่งรวมถึง พาสคีย์ รหัสผ่าน และโซลูชันการลงชื่อเข้าใช้แบบรวม เช่น ลงชื่อเข้าใช้ด้วย Google

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

เฟรมเวิร์กการป้อนข้อความอัตโนมัติของ Android ช่วยให้กระบวนการลงชื่อสมัครใช้และลงชื่อเข้าใช้ง่ายขึ้น ลดอัตราข้อผิดพลาดและอุปสรรคของผู้ใช้ การป้อนอัตโนมัติจะผสานรวมกับเครื่องมือจัดการรหัสผ่าน เพื่อให้ผู้ใช้เลือกรหัสผ่านที่ซับซ้อนและสุ่ม ซึ่งสามารถ จัดเก็บและเรียกข้อมูลได้อย่างง่ายดายและปลอดภัย

ความสมบูรณ์ของแอป

Play Integrity API จะช่วยคุณตรวจสอบว่าการโต้ตอบและคำขอของเซิร์ฟเวอร์มาจากไบนารีของแอปจริงที่ทำงานในอุปกรณ์ที่ใช้ Android ของแท้ การตรวจจับการโต้ตอบที่อาจมีความเสี่ยงและเป็นการฉ้อโกง เช่น จากแอปเวอร์ชันที่มีการดัดแปลงและสภาพแวดล้อมที่ไม่น่าเชื่อถือ จะช่วยให้เซิร์ฟเวอร์แบ็กเอนด์ของแอปตอบสนองด้วยการดำเนินการที่เหมาะสมเพื่อป้องกันการโจมตีและลดการละเมิดได้

การจัดเก็บข้อมูล

ข้อกังวลด้านความปลอดภัยที่พบบ่อยที่สุดสำหรับแอปพลิเคชันใน Android คือแอปอื่นๆ จะเข้าถึงข้อมูลที่คุณบันทึกไว้ในอุปกรณ์ได้หรือไม่ วิธีพื้นฐานในการบันทึกข้อมูลในอุปกรณ์มี 3 วิธีดังนี้

  • ที่เก็บข้อมูลภายใน
  • ที่จัดเก็บข้อมูลภายนอก
  • ผู้ให้บริการเนื้อหา

ส่วนต่อไปนี้จะอธิบายปัญหาด้านความปลอดภัยที่เกี่ยวข้องกับแต่ละ แนวทาง

ที่เก็บข้อมูลภายใน

โดยค่าเริ่มต้น ไฟล์ที่คุณสร้างในที่จัดเก็บข้อมูลภายในจะเข้าถึงได้เฉพาะแอปของคุณเท่านั้น Android จะใช้การป้องกันนี้ และเพียงพอสำหรับแอปพลิเคชันส่วนใหญ่

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

ที่จัดเก็บข้อมูลภายนอก

ไฟล์ที่สร้างในที่เก็บข้อมูลภายนอก เช่น การ์ด SD จะอ่านและเขียนได้ทั่วโลก เนื่องจากผู้ใช้สามารถนำที่จัดเก็บข้อมูลภายนอกออกได้และแอปพลิเคชันใดก็ได้สามารถแก้ไขที่จัดเก็บข้อมูลภายนอกได้ ดังนั้นให้จัดเก็บเฉพาะข้อมูลที่ไม่ละเอียดอ่อนโดยใช้ที่จัดเก็บข้อมูลภายนอก

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

ผู้ให้บริการเนื้อหา

ผู้ให้บริการเนื้อหามีกลไกการจัดเก็บที่มีโครงสร้างซึ่งจำกัดได้ เฉพาะแอปพลิเคชันของคุณเองหรือส่งออกเพื่อให้แอปพลิเคชันอื่นๆ เข้าถึงได้ หากคุณไม่ต้องการให้แอปพลิเคชันอื่นๆ เข้าถึง ContentProvider ให้ทำเครื่องหมายเป็น android:exported=false ในไฟล์ Manifest ของแอปพลิเคชัน หรือตั้งค่าแอตทริบิวต์ android:exported เป็น true เพื่อให้แอปอื่นๆ เข้าถึงข้อมูลที่จัดเก็บได้

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

หากคุณใช้ผู้ให้บริการเนื้อหาเพื่อแชร์ข้อมูลระหว่างแอปของคุณเองเท่านั้น เราขอแนะนำให้ใช้ชุดแอตทริบิวต์ android:protectionLevel ที่ตั้งค่าเป็น signature protection สิทธิ์ลายเซ็นไม่จำเป็นต้องมีการยืนยันจากผู้ใช้ จึงมอบประสบการณ์การใช้งานที่ดีขึ้นและควบคุมการเข้าถึงข้อมูลของผู้ให้บริการเนื้อหาได้มากขึ้น เมื่อแอปที่เข้าถึงข้อมูลลงนามด้วยคีย์เดียวกัน

ผู้ให้บริการเนื้อหายังให้สิทธิ์เข้าถึงที่ละเอียดยิ่งขึ้นได้ด้วยการประกาศแอตทริบิวต์ android:grantUriPermissions และใช้แฟล็ก FLAG_GRANT_READ_URI_PERMISSION และ FLAG_GRANT_WRITE_URI_PERMISSION ในออบเจ็กต์ Intent ที่ เปิดใช้งานคอมโพเนนต์ ขอบเขตของสิทธิ์เหล่านี้สามารถจำกัดเพิ่มเติมได้ โดยองค์ประกอบ <grant-uri-permission>

เมื่อเข้าถึง Content Provider ให้ใช้วิธีการค้นหาแบบพารามิเตอร์ เช่น query, update และ delete() เพื่อหลีกเลี่ยงการแทรก SQL ที่อาจเกิดขึ้น จากแหล่งที่มาที่ไม่น่าเชื่อถือ โปรดทราบว่าการใช้วิธีการที่กำหนดพารามิเตอร์ไม่เพียงพอ หากมีการสร้างอาร์กิวเมนต์ selection โดยการต่อข้อมูลผู้ใช้ก่อนที่จะส่งไปยังวิธีการ

อย่ารู้สึกว่าสิทธิ์เขียนมีความปลอดภัยอย่างแท้จริง สิทธิ์เขียน ช่วยให้ใช้คำสั่ง SQL ที่ทำให้ยืนยันข้อมูลบางอย่างได้โดยใช้ คําสั่ง WHERE ของครีเอทีฟโฆษณาและการแยกวิเคราะห์ผลลัพธ์ ตัวอย่างเช่น ผู้โจมตีอาจตรวจสอบว่ามีหมายเลขโทรศัพท์ที่เฉพาะเจาะจงในบันทึกการโทรหรือไม่ โดยแก้ไขแถวเฉพาะในกรณีที่มีหมายเลขโทรศัพท์นั้นอยู่แล้ว หากข้อมูลผู้ให้บริการเนื้อหามีโครงสร้างที่คาดการณ์ได้ สิทธิ์เขียนอาจเทียบเท่ากับการให้ทั้งสิทธิ์อ่านและเขียน

สิทธิ์

เนื่องจาก Android แยกแอปพลิเคชันออกจากกัน แอปพลิเคชันจึงต้องแชร์ทรัพยากรและข้อมูลอย่างชัดเจน โดยทำได้ด้วยการประกาศสิทธิ์ ที่จำเป็นสำหรับความสามารถเพิ่มเติมที่แซนด์บ็อกซ์พื้นฐานไม่มีให้ รวมถึงสิทธิ์เข้าถึงฟีเจอร์ของอุปกรณ์ เช่น กล้อง

คำขอสิทธิ์

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

หากเป็นไปได้ ให้ออกแบบแอปพลิเคชันในลักษณะที่ไม่ต้องใช้สิทธิ์ใดๆ เช่น แทนที่จะขอสิทธิ์เข้าถึงข้อมูลอุปกรณ์เพื่อ สร้างตัวระบุที่ไม่ซ้ำกัน ให้สร้าง UUID สำหรับแอปพลิเคชันของคุณ (ดูข้อมูลเพิ่มเติมได้ในส่วนเกี่ยวกับข้อมูลผู้ใช้) หรือจะจัดเก็บข้อมูลไว้ในที่จัดเก็บข้อมูลภายในแทนการใช้ที่จัดเก็บข้อมูลภายนอก (ซึ่งต้องได้รับสิทธิ์) ก็ได้

นอกเหนือจากการขอสิทธิ์แล้ว แอปพลิเคชันยังใช้ องค์ประกอบ <permission> เพื่อปกป้อง IPC ที่มีความละเอียดอ่อนด้านความปลอดภัยและ แสดงต่อแอปพลิเคชันอื่นๆ เช่น ContentProvider ได้ด้วย โดยทั่วไป เราขอแนะนำให้ใช้การควบคุมการเข้าถึงอื่นๆ นอกเหนือจากสิทธิ์ที่ผู้ใช้ยืนยันหากเป็นไปได้ เนื่องจากสิทธิ์อาจทำให้ผู้ใช้สับสน ตัวอย่างเช่น ให้พิจารณา ใช้ระดับการปกป้องลายเซ็นในสิทธิ์สำหรับการสื่อสาร IPC ระหว่างแอปพลิเคชันที่นักพัฒนาแอปรายเดียวเป็นผู้ให้บริการ

อย่าทำให้ข้อมูลที่ได้รับการปกป้องด้วยสิทธิ์รั่วไหล กรณีนี้จะเกิดขึ้นเมื่อแอปของคุณเปิดเผยข้อมูลผ่าน IPC ซึ่งจะใช้ได้ก็ต่อเมื่อแอปมีสิทธิ์เข้าถึงข้อมูลนั้น ไคลเอ็นต์ของอินเทอร์เฟซ IPC ของแอปอาจไม่มีสิทธิ์เข้าถึงข้อมูลเดียวกันนั้น รายละเอียดเพิ่มเติมเกี่ยวกับความถี่และผลกระทบที่อาจเกิดขึ้นจากปัญหานี้ ปรากฏในเอกสารงานวิจัยการมอบสิทธิ์อีกครั้ง: การโจมตีและการป้องกัน ซึ่งเผยแพร่ที่ USENIX

คำจำกัดความของสิทธิ์

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

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

หากยังจำเป็นต้องสร้างสิทธิ์ใหม่ ให้ประกาศในไฟล์ Manifest ของแอป โดยใช้แท็ก <permission> แอปที่ใช้สิทธิ์ใหม่จะอ้างอิงสิทธิ์ดังกล่าวได้โดยการเพิ่มองค์ประกอบ <uses-permission> ในไฟล์ Manifest นอกจากนี้ คุณยังเพิ่มสิทธิ์แบบไดนามิกได้โดยใช้วิธี addPermission()

หากสร้างสิทธิ์ที่มีระดับการปกป้องที่เป็นอันตราย คุณจะต้องพิจารณาความซับซ้อนหลายอย่าง ดังนี้

  • สิทธิ์ต้องมีสตริงที่อธิบายให้ผู้ใช้ทราบอย่างกระชับถึง การตัดสินใจด้านความปลอดภัยที่ผู้ใช้ต้องทำ
  • สตริงสิทธิ์ต้องได้รับการแปลเป็นภาษาต่างๆ
  • ผู้ใช้อาจเลือกที่จะไม่ติดตั้งแอปพลิเคชันเนื่องจากสิทธิ์นั้น สร้างความสับสนหรือดูมีความเสี่ยง
  • แอปพลิเคชันอาจขอสิทธิ์เมื่อไม่ได้ติดตั้งผู้สร้างสิทธิ์

แต่ละข้อเหล่านี้เป็นความท้าทายที่สำคัญที่ไม่ใช่ด้านเทคนิคสำหรับคุณในฐานะ นักพัฒนาแอป และยังสร้างความสับสนให้กับผู้ใช้ด้วย ซึ่งเป็นเหตุผลที่เราไม่แนะนำให้ใช้ สิทธิ์ระดับอันตราย

เครือข่าย

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

เครือข่าย IP

การเชื่อมต่อเครือข่ายใน Android ไม่แตกต่างจากสภาพแวดล้อม Linux อื่นๆ มากนัก ข้อควรพิจารณาที่สำคัญคือการตรวจสอบว่ามีการใช้โปรโตคอลที่เหมาะสม สำหรับข้อมูลที่ละเอียดอ่อน เช่น HttpsURLConnection สำหรับเว็บ ที่มีการรักษาความปลอดภัย ใช้ HTTPS แทน HTTP ทุกที่ที่เซิร์ฟเวอร์รองรับ HTTPS เนื่องจากอุปกรณ์เคลื่อนที่มักเชื่อมต่อในเครือข่ายที่ไม่ปลอดภัย เช่น ฮอตสปอต Wi-Fi สาธารณะ

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

แอปพลิเคชันบางอย่างใช้พอร์ตเครือข่าย localhost เพื่อจัดการ IPC ที่ละเอียดอ่อน อย่าใช้วิธีนี้เนื่องจากแอปพลิเคชันอื่นๆ ในอุปกรณ์เข้าถึงอินเทอร์เฟซเหล่านี้ได้ แต่ให้ใช้กลไก IPC ของ Android ที่สามารถทำการตรวจสอบสิทธิ์ได้ เช่น Service การเชื่อมโยงกับที่อยู่ IP ที่ไม่เฉพาะเจาะจง INADDR_ANY แย่กว่าการใช้ลูปแบ็ก เนื่องจากจะอนุญาตให้แอปพลิเคชันรับคำขอจากที่อยู่ IP ใดก็ได้

ตรวจสอบว่าคุณไม่ได้เชื่อถือข้อมูลที่ดาวน์โหลดจาก HTTP หรือโปรโตคอลอื่นๆ ที่ไม่ปลอดภัย ซึ่งรวมถึงการตรวจสอบอินพุตใน WebView และการตอบกลับใดๆ ต่อ Intent ที่ออกกับ HTTP

การเชื่อมต่อเครือข่ายโทรศัพท์

โปรโตคอลบริการข้อความสั้น (SMS) ได้รับการออกแบบมาเพื่อการสื่อสารระหว่างผู้ใช้เป็นหลัก และไม่เหมาะสำหรับแอปที่ต้องการโอนข้อมูล เนื่องจากข้อจำกัดของ SMS เราขอแนะนำให้ใช้ Firebase Cloud Messaging (FCM) และการเชื่อมต่อเครือข่าย IP เพื่อส่งข้อความข้อมูลจากเว็บเซิร์ฟเวอร์ไปยังแอปในอุปกรณ์ของผู้ใช้

โปรดทราบว่า SMS ไม่ได้เข้ารหัสและไม่ได้มีการตรวจสอบสิทธิ์ที่รัดกุมทั้งใน เครือข่ายและอุปกรณ์ โดยเฉพาะอย่างยิ่ง ผู้รับ SMS ทุกคนควรคาดการณ์ว่าผู้ใช้ที่เป็นอันตรายอาจส่ง SMS ไปยังแอปพลิเคชันของคุณ อย่าใช้ข้อมูล SMS ที่ไม่ได้ตรวจสอบสิทธิ์เพื่อเรียกใช้คำสั่งที่ละเอียดอ่อน นอกจากนี้ โปรดทราบว่า SMS อาจถูกสวมรอยและ/หรือดักฟังในเครือข่าย ในอุปกรณ์ที่ใช้ Android เอง ข้อความ SMS จะส่งเป็น Intent การออกอากาศ ดังนั้นแอปพลิเคชันอื่นๆ ที่มีสิทธิ์ READ_SMS จะอ่านหรือจับภาพข้อความได้

การตรวจสอบข้อมูลที่ป้อน

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

หากคุณใช้โค้ดดั้งเดิม ข้อมูลใดก็ตามที่อ่านจากไฟล์ ได้รับผ่านเครือข่าย หรือได้รับจาก IPC อาจทำให้เกิดปัญหาด้านความปลอดภัย ปัญหาที่พบบ่อยที่สุดคือบัฟเฟอร์โอเวอร์โฟลว์ ใช้หลังจากปล่อย และข้อผิดพลาดแบบออฟบายวัน Android มีเทคโนโลยีหลายอย่าง เช่น ASLR และการป้องกันการดำเนินการข้อมูล (DEP) ซึ่งช่วยลดความเสี่ยงในการใช้ประโยชน์จากข้อผิดพลาดเหล่านี้ แต่ก็ไม่ได้แก้ปัญหา ที่ต้นเหตุ คุณป้องกันช่องโหว่เหล่านี้ได้โดยการจัดการ พอยน์เตอร์และจัดการบัฟเฟอร์อย่างระมัดระวัง

ภาษาแบบไดนามิกที่อิงตามสตริง เช่น JavaScript และ SQL ก็อาจประสบปัญหาการแทรกสคริปต์เนื่องจากอักขระหลีก

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

หากใช้ฟีเจอร์ความปลอดภัยที่กล่าวถึงในส่วนนี้ไม่ได้ โปรด ใช้รูปแบบข้อมูลที่มีโครงสร้างดีและตรวจสอบว่าข้อมูลเป็นไปตามรูปแบบที่คาดไว้ แม้ว่าการบล็อกอักขระที่เฉพาะเจาะจงหรือการแทนที่อักขระ อาจเป็นกลยุทธ์ที่มีประสิทธิภาพ แต่ในทางปฏิบัติเทคนิคเหล่านี้มักเกิดข้อผิดพลาดได้ง่าย และเราขอแนะนำให้หลีกเลี่ยงหากเป็นไปได้

ข้อมูลผู้ใช้

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

ตรวจสอบสิทธิ์ผู้ใช้ทุกครั้งที่ต้องเข้าถึงข้อมูลส่วนตัว และใช้วิธีการตรวจสอบสิทธิ์ที่ทันสมัย เช่น พาสคีย์และเครื่องมือจัดการข้อมูลเข้าสู่ระบบ หากแอปจำเป็นต้องเข้าถึงข้อมูลส่วนตัว โปรดทราบว่าเขตอำนาจศาลบางแห่งอาจกำหนดให้คุณต้องระบุนโยบายความเป็นส่วนตัวที่อธิบายการใช้และการจัดเก็บข้อมูลดังกล่าว ปฏิบัติตามแนวทางปฏิบัติแนะนำด้านความปลอดภัยในการลด การเข้าถึงข้อมูลผู้ใช้เพื่อลดความซับซ้อนในการปฏิบัติตามข้อกำหนด

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

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

หากต้องใช้ตัวระบุที่ไม่ซ้ำกันทั่วโลก (GUID) ให้สร้างตัวเลขขนาดใหญ่ที่ไม่ซ้ำกัน แล้วจัดเก็บไว้ อย่าใช้ตัวระบุโทรศัพท์ เช่น หมายเลขโทรศัพท์หรือ IMEI ซึ่งอาจเชื่อมโยงกับข้อมูลส่วนบุคคล หัวข้อนี้มีการอธิบายรายละเอียดเพิ่มเติมในหน้าเกี่ยวกับแนวทางปฏิบัติแนะนำสำหรับตัวระบุที่ไม่ซ้ำกัน

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

WebView

เนื่องจาก WebView ใช้เนื้อหาเว็บซึ่งอาจมี HTML และ JavaScript การใช้งานที่ไม่เหมาะสมอาจทำให้เกิดปัญหาด้านความปลอดภัยบนเว็บทั่วไป เช่น Cross-site Scripting (การแทรก JavaScript) Android มีกลไกหลายอย่างเพื่อลดขอบเขตของปัญหาที่อาจเกิดขึ้นเหล่านี้โดยการจำกัดความสามารถของ WebView ให้เหลือเพียงฟังก์ชันการทำงานขั้นต่ำที่แอปพลิเคชันของคุณต้องการ

หากแอปพลิเคชันไม่ได้ใช้ JavaScript โดยตรงภายใน WebView อย่า เรียกใช้ setJavaScriptEnabled โค้ดตัวอย่างบางรายการใช้วิธีนี้ หากคุณนำโค้ดตัวอย่างที่ใช้วิธีนี้ไปใช้ซ้ำในแอปพลิเคชันที่ใช้งานจริง ให้นำการเรียกใช้เมธอดนั้นออกหากไม่จำเป็น โดยค่าเริ่มต้น WebView จะไม่เรียกใช้ JavaScript จึงไม่สามารถใช้ Cross-site Scripting ได้

โปรดใช้ addJavaScriptInterface() ด้วยความระมัดระวังเป็นพิเศษ เนื่องจากจะช่วยให้ JavaScript เรียกใช้การดำเนินการที่ปกติสงวนไว้สำหรับแอปพลิเคชัน Android หากคุณใช้ฟีเจอร์นี้ ให้แสดง addJavaScriptInterface() เฉพาะในหน้าเว็บ ที่รับประกันได้ว่าข้อมูลทั้งหมดที่ป้อนนั้นเชื่อถือได้ หากอนุญาตอินพุตที่ไม่น่าเชื่อถือ JavaScript ที่ไม่น่าเชื่อถืออาจเรียกใช้เมธอด Android ภายในแอปได้ โดยทั่วไป เราขอแนะนำให้เปิดเผย addJavaScriptInterface() เฉพาะกับ JavaScript ที่อยู่ใน APK ของแอปพลิเคชัน

หากแอปพลิเคชันของคุณเข้าถึงข้อมูลที่ละเอียดอ่อนด้วย WebView ให้พิจารณาใช้วิธี clearCache() เพื่อลบไฟล์ที่จัดเก็บไว้ในเครื่อง คุณยังใช้ส่วนหัวฝั่งเซิร์ฟเวอร์ เช่น no-store เพื่อระบุว่าแอปพลิเคชันไม่ควรแคชเนื้อหาบางอย่างได้ด้วย

อุปกรณ์ที่ใช้แพลตฟอร์มเก่ากว่า Android 4.4 (ระดับ API 19) จะใช้ webkit เวอร์ชันที่มีปัญหาด้านความปลอดภัยหลายประการ วิธีแก้ปัญหาชั่วคราวคือ หากแอปของคุณทำงานบนอุปกรณ์เหล่านี้ แอปจะต้องยืนยันว่าออบเจ็กต์ WebView แสดงเฉพาะเนื้อหาที่เชื่อถือได้ หากต้องการให้มั่นใจว่าแอปของคุณจะไม่เสี่ยงต่อช่องโหว่ที่อาจเกิดขึ้นใน SSL ให้ใช้ออบเจ็กต์ความปลอดภัยที่อัปเดตได้ Provider ตามที่อธิบายไว้ในอัปเดตผู้ให้บริการรักษาความปลอดภัยเพื่อป้องกันการแสวงหาประโยชน์จาก SSL หากแอปพลิเคชันของคุณต้องแสดงเนื้อหาจากเว็บแบบเปิด ให้พิจารณาจัดเตรียมโปรแกรมแสดงผลของคุณเองเพื่อให้คุณอัปเดตโปรแกรมแสดงผลให้เป็นเวอร์ชันล่าสุดที่มี แพตช์ความปลอดภัยล่าสุดอยู่เสมอ

คำขอข้อมูลเข้าสู่ระบบ

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

ลดการเปิดเผยข้อมูลเข้าสู่ระบบ

  • หลีกเลี่ยงการขอข้อมูลเข้าสู่ระบบที่ไม่จำเป็น หากต้องการทำให้การโจมตีแบบฟิชชิงสังเกตได้ง่ายขึ้นและมีโอกาสสำเร็จน้อยลง ให้ลดความถี่ในการขอข้อมูลเข้าสู่ระบบของผู้ใช้ แต่ให้ใช้โทเค็นการให้สิทธิ์และรีเฟรชโทเค็น ขอเฉพาะข้อมูลเข้าสู่ระบบขั้นต่ำที่จำเป็นสำหรับการตรวจสอบสิทธิ์และการให้สิทธิ์
  • จัดเก็บข้อมูลเข้าสู่ระบบอย่างปลอดภัย ใช้Credential Managerเพื่อเปิดใช้การตรวจสอบสิทธิ์แบบไม่มีรหัสผ่านโดยใช้พาสคีย์ หรือเพื่อใช้การลงชื่อเข้าใช้แบบรวมโดยใช้รูปแบบต่างๆ เช่น การลงชื่อเข้าใช้ด้วย Google หากต้องใช้การตรวจสอบสิทธิ์ด้วยรหัสผ่านแบบเดิม อย่าจัดเก็บรหัสผู้ใช้และรหัสผ่านในอุปกรณ์ แต่ให้ทำการตรวจสอบสิทธิ์เริ่มต้นโดยใช้ชื่อผู้ใช้และรหัสผ่านที่ผู้ใช้ระบุ จากนั้นใช้โทเค็นการให้สิทธิ์แบบเฉพาะบริการที่มีอายุสั้น
  • จำกัดขอบเขตของสิทธิ์ อย่าขอสิทธิ์แบบกว้างสำหรับ งานที่ต้องใช้ขอบเขตที่แคบกว่า
  • จำกัดโทเค็นเพื่อการเข้าถึง ใช้การดำเนินการโทเค็นแบบมีอายุสั้นและการเรียก API
  • จำกัดอัตราการตรวจสอบสิทธิ์ การตรวจสอบสิทธิ์หรือ คำขอการให้สิทธิ์ที่รวดเร็วและต่อเนื่องอาจเป็นสัญญาณของการโจมตีแบบ Brute Force จำกัดอัตราเหล่านี้ให้มีความถี่ที่สมเหตุสมผลในขณะที่ยังคงมอบประสบการณ์การใช้งานแอปที่ใช้งานได้และเป็นมิตรกับผู้ใช้

ใช้การตรวจสอบสิทธิ์ที่ปลอดภัย

  • ใช้พาสคีย์ เปิดใช้พาสคีย์เพื่ออัปเกรดรหัสผ่านให้ปลอดภัยและเป็นมิตรกับผู้ใช้มากขึ้น
  • เพิ่มไบโอเมตริก มีตัวเลือกให้ใช้การตรวจสอบสิทธิ์ด้วยข้อมูลไบโอเมตริก เช่น ลายนิ้วมือหรือการจดจำใบหน้า เพื่อเพิ่มความปลอดภัย
  • ใช้ผู้ให้บริการข้อมูลประจำตัวแบบรวม Credential Manager รองรับผู้ให้บริการการตรวจสอบสิทธิ์แบบรวม เช่น ลงชื่อเข้าใช้ด้วย Google
  • เข้ารหัสการสื่อสาร ใช้ HTTPS และเทคโนโลยีที่คล้ายกันเพื่อให้มั่นใจว่าข้อมูลที่แอปส่งผ่านเครือข่ายได้รับการปกป้อง

ฝึกการจัดการบัญชีอย่างปลอดภัย

  • เชื่อมต่อกับบริการที่แอปพลิเคชันหลายรายการเข้าถึงได้โดยใช้ AccountManager ใช้คลาส AccountManager เพื่อเรียกใช้บริการบนระบบคลาวด์ และอย่าจัดเก็บรหัสผ่านไว้ในอุปกรณ์
  • หลังจากใช้ AccountManager เพื่อดึงข้อมูล Account แล้ว ให้ใช้ CREATOR ก่อนส่งข้อมูลเข้าสู่ระบบ เพื่อไม่ให้ ส่งข้อมูลเข้าสู่ระบบไปยังแอปพลิเคชันที่ไม่ถูกต้องโดยไม่ตั้งใจ
  • หากใช้ข้อมูลเข้าสู่ระบบเฉพาะในแอปพลิเคชันที่คุณสร้างขึ้น คุณจะยืนยัน แอปพลิเคชันที่เข้าถึง AccountManager ได้โดยใช้ checkSignatures หรือหากมีเพียงแอปพลิเคชันเดียวที่ใช้ ข้อมูลเข้าสู่ระบบ คุณอาจใช้ KeyStore สำหรับการจัดเก็บ

ระมัดระวัง

  • อัปเดตรหัสให้เป็นข้อมูลล่าสุดอยู่เสมอ อย่าลืมอัปเดตซอร์สโค้ด ซึ่งรวมถึงไลบรารีและทรัพยากร Dependency ของบุคคลที่สาม เพื่อป้องกันช่องโหว่ล่าสุด
  • ตรวจสอบกิจกรรมที่น่าสงสัย มองหาการใช้ในทางที่ผิดที่อาจเกิดขึ้น เช่น รูปแบบของการใช้ในทางที่ผิดการให้สิทธิ์
  • ตรวจสอบโค้ด ตรวจสอบความปลอดภัยในโค้ดเบสเป็นประจำเพื่อ มองหาปัญหาที่อาจเกิดขึ้นกับการขอข้อมูลเข้าสู่ระบบ

การจัดการคีย์ API

คีย์ API เป็นคอมโพเนนต์ที่สำคัญของแอป Android หลายแอป ซึ่งช่วยให้แอปเข้าถึง บริการภายนอกและทําฟังก์ชันที่จําเป็น เช่น การเชื่อมต่อกับบริการ การแมป การตรวจสอบสิทธิ์ และบริการสภาพอากาศ อย่างไรก็ตาม การเปิดเผยคีย์ที่ละเอียดอ่อนเหล่านี้อาจส่งผลกระทบร้ายแรง ซึ่งรวมถึงการละเมิดข้อมูล การเข้าถึงที่ไม่ได้รับอนุญาต และการสูญเสียทางการเงิน นักพัฒนาแอปควรใช้กลยุทธ์ที่ปลอดภัยในการจัดการคีย์ API ตลอดกระบวนการพัฒนาเพื่อป้องกันสถานการณ์ดังกล่าว

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

ส่วนนี้มีไว้สำหรับนักพัฒนาแอป Android 2 กลุ่ม ได้แก่ ผู้ที่ทำงานร่วมกับทีมโครงสร้างพื้นฐานในไปป์ไลน์การส่งมอบอย่างต่อเนื่อง และผู้ที่นำแอปแบบสแตนด์อโลนไปใช้งานใน Play Store ส่วนนี้จะอธิบายแนวทางปฏิบัติแนะนำ สำหรับวิธีจัดการคีย์ API เพื่อให้แอปสื่อสารกับบริการได้อย่างปลอดภัย

การสร้างและการจัดเก็บ

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

การจัดเก็บคีย์ที่รัดกุม

เพื่อความปลอดภัยในการจัดการคีย์ที่ดีที่สุด ให้ใช้ Android Keystore และเข้ารหัส คีย์ที่จัดเก็บโดยใช้เครื่องมือที่มีประสิทธิภาพ เช่น Tink Java

การยกเว้นการควบคุมแหล่งที่มา

อย่าคอมมิตคีย์ API ไปยังที่เก็บซอร์สโค้ด การเพิ่มคีย์ API ลงในซอร์สโค้ด อาจทำให้คีย์ดังกล่าวแสดงในที่เก็บสาธารณะ ตัวอย่างโค้ดที่แชร์ และ ไฟล์ที่แชร์โดยไม่ตั้งใจ แต่ให้ใช้ปลั๊กอิน Gradle เช่น secrets-gradle-plugin เพื่อทำงานกับคีย์ API ในโปรเจ็กต์แทน

คีย์เฉพาะสภาพแวดล้อม

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

การควบคุมการใช้งานและการเข้าถึง

แนวทางปฏิบัติเกี่ยวกับคีย์ API ที่ปลอดภัยเป็นสิ่งสำคัญในการปกป้อง API และผู้ใช้ วิธีเตรียมคีย์เพื่อความปลอดภัยสูงสุดมีดังนี้

  • สร้างคีย์ที่ไม่ซ้ำกันสำหรับแต่ละแอป: ใช้คีย์ API แยกต่างหากสำหรับแต่ละแอปเพื่อช่วยระบุและแยกการเข้าถึงที่ถูกบุกรุก
  • ใช้ข้อจำกัด IP: หากเป็นไปได้ ให้จำกัดการใช้งานคีย์ API สำหรับที่อยู่หรือช่วง IP ที่เฉพาะเจาะจง
  • จำกัดการใช้งานคีย์ของแอปบนอุปกรณ์เคลื่อนที่: จำกัดการใช้งานคีย์ API สำหรับแอปบนอุปกรณ์เคลื่อนที่ที่เฉพาะเจาะจงโดยการรวมคีย์ไว้กับแอปหรือใช้ใบรับรองแอป
  • บันทึกและตรวจสอบกิจกรรมที่น่าสงสัย: ใช้กลไกการบันทึกและการตรวจสอบการใช้งาน API เพื่อตรวจหากิจกรรมที่น่าสงสัยและป้องกันการละเมิดที่อาจเกิดขึ้น

หมายเหตุ: บริการของคุณควรมีฟีเจอร์สำหรับจำกัดคีย์ไว้สำหรับแพ็กเกจหรือแพลตฟอร์มใดแพลตฟอร์มหนึ่ง เช่น Google Maps API จำกัดการเข้าถึงคีย์ตามชื่อแพ็กเกจและคีย์การลงนาม

OAuth 2.0 มีเฟรมเวิร์กสำหรับการให้สิทธิ์เข้าถึงทรัพยากร โดยจะกำหนดมาตรฐานสำหรับวิธีที่ไคลเอ็นต์และเซิร์ฟเวอร์ควรโต้ตอบกัน และอนุญาตให้มีการให้สิทธิ์ที่ปลอดภัย คุณสามารถใช้ OAuth 2.0 เพื่อจำกัดการใช้คีย์ API ให้กับไคลเอ็นต์ที่เฉพาะเจาะจง และกำหนดขอบเขตการเข้าถึงเพื่อให้คีย์ API แต่ละรายการมีสิทธิ์เข้าถึงในระดับต่ำสุดที่จำเป็นสำหรับวัตถุประสงค์ที่ต้องการเท่านั้น

การหมุนเวียนคีย์และการหมดอายุ

การหมุนเวียนคีย์ API เป็นประจำจะช่วยลดความเสี่ยงของการเข้าถึงโดยไม่ได้รับอนุญาตผ่านช่องโหว่ของ API ที่ยังไม่พบ มาตรฐาน ISO 27001 กำหนดกรอบการปฏิบัติตามข้อกำหนดสำหรับความถี่ในการหมุนเวียนคีย์ ในกรณีส่วนใหญ่ ระยะเวลาการหมุนเวียนคีย์ระหว่าง 90 วันถึง 6 เดือนควรเพียงพอ การใช้ระบบการจัดการคีย์ที่มีประสิทธิภาพจะช่วยให้คุณปรับปรุงกระบวนการเหล่านี้ เพิ่มประสิทธิภาพการหมุนเวียนคีย์ และตอบสนองความต้องการด้านการหมดอายุของคีย์

แนวทางปฏิบัติแนะนำโดยทั่วไป

  • ใช้ SSL/HTTPS: ใช้การสื่อสารผ่าน HTTPS เสมอเพื่อเข้ารหัสคำขอ API
  • การตรึงใบรับรอง: หากต้องการเพิ่มความปลอดภัยอีกขั้น คุณอาจพิจารณา ใช้การตรึงใบรับรองเพื่อตรวจสอบว่าใบรับรองใดที่ ถือว่าถูกต้อง
  • ตรวจสอบและปรับปรุงข้อมูลจากผู้ใช้: ตรวจสอบและปรับปรุงข้อมูลจากผู้ใช้เพื่อป้องกันการโจมตีแบบแทรกโค้ดที่อาจเปิดเผยคีย์ API
  • ปฏิบัติตามแนวทางปฏิบัติแนะนำด้านความปลอดภัย: ใช้แนวทางปฏิบัติแนะนำด้านความปลอดภัยทั่วไป ในกระบวนการพัฒนา ซึ่งรวมถึงเทคนิคการเขียนโค้ดที่ปลอดภัย การตรวจสอบโค้ด และการสแกนช่องโหว่
  • รับทราบข้อมูล: ติดตามข่าวสารล่าสุดเกี่ยวกับภัยคุกคามด้านความปลอดภัยและแนวทางปฏิบัติแนะนำ สำหรับการจัดการคีย์ API
  • SDK เป็นเวอร์ชันล่าสุด: ตรวจสอบว่า SDK และไลบรารีได้รับการอัปเดตเป็น เวอร์ชันล่าสุด

การเข้ารหัสลับ

นอกเหนือจากการแยกข้อมูล การรองรับการเข้ารหัสระบบไฟล์แบบเต็ม และการจัดเตรียมช่องทางการสื่อสารที่ปลอดภัยแล้ว Android ยังมีอัลกอริทึมมากมาย สำหรับการปกป้องข้อมูลโดยใช้การเข้ารหัส

ทราบว่าซอฟต์แวร์ของคุณใช้ผู้ให้บริการด้านความปลอดภัยของ Java Cryptography Architecture (JCA) รายใด พยายามใช้การติดตั้งใช้งานเฟรมเวิร์กที่มีอยู่ก่อนแล้วในระดับสูงสุด ที่รองรับกรณีการใช้งานของคุณ หากเกี่ยวข้อง ให้ใช้ผู้ให้บริการที่ Google ระบุ ตามลำดับที่ Google กำหนด

หากต้องการดึงข้อมูลไฟล์จากตำแหน่งเครือข่ายที่ทราบอย่างปลอดภัย URI ของ HTTPS อย่างง่ายอาจเพียงพอและไม่จำเป็นต้องมีความรู้ด้านวิทยาการเข้ารหัส หากต้องการใช้การเชื่อมต่อที่ปลอดภัย ให้ลองใช้ HttpsURLConnection หรือ SSLSocket แทนการเขียนโปรโตคอลของคุณเอง หากใช้ SSLSocket โปรดทราบว่า SSLSocket ไม่ได้ทำการยืนยันชื่อโฮสต์ ดูคำเตือนเกี่ยวกับการใช้ SSLSocket โดยตรง

หากพบว่าคุณจำเป็นต้องใช้โปรโตคอลของคุณเอง โปรดอย่าใช้ อัลกอริทึมการเข้ารหัสของคุณเอง ใช้อัลกอริทึมการเข้ารหัสที่มีอยู่ เช่น การใช้งาน AES และ RSA ที่ระบุไว้ในคลาส Cipher นอกจากนี้ ให้ทำตามแนวทางปฏิบัติแนะนำต่อไปนี้

  • ใช้ AES 256 บิตเพื่อวัตถุประสงค์เชิงพาณิชย์ (หากไม่มี ให้ใช้ AES แบบ 128 บิต)
  • ใช้ขนาดคีย์สาธารณะ 224 หรือ 256 บิตสำหรับการเข้ารหัสแบบโค้งรี (EC)
  • ทราบว่าควรใช้โหมดบล็อก CBC, CTR หรือ GCM เมื่อใด
  • หลีกเลี่ยงการใช้ IV/ตัวนับซ้ำในโหมด CTR ตรวจสอบว่าค่าเหล่านั้นเป็นแบบสุ่ม ที่เข้ารหัส
  • เมื่อใช้การเข้ารหัส ให้ใช้การตรวจสอบความสมบูรณ์โดยใช้โหมด CBC หรือ CTR กับฟังก์ชันใดฟังก์ชันหนึ่งต่อไปนี้
    • HMAC-SHA1
    • HMAC-SHA-256
    • HMAC-SHA-512
    • โหมด GCM

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

หากต้องการจัดเก็บคีย์เพื่อใช้ซ้ำ ให้ใช้กลไก เช่น KeyStore ซึ่งมีพื้นที่เก็บข้อมูลระยะยาวและการดึงคีย์การเข้ารหัส

การสื่อสารระหว่างโปรเซส

แอปบางแอปพยายามใช้ IPC โดยใช้เทคนิค Linux แบบดั้งเดิม เช่น ซ็อกเก็ตเครือข่ายและไฟล์ที่แชร์ อย่างไรก็ตาม เราขอแนะนำให้คุณใช้ฟังก์ชันการทำงานของระบบ Android สำหรับ IPC เช่น Intent, Binder หรือ Messenger กับ Service และ BroadcastReceiver แทน กลไก IPC ของ Android ช่วยให้คุณยืนยันตัวตนของแอปพลิเคชันที่เชื่อมต่อกับ IPC และตั้งค่านโยบายความปลอดภัยสำหรับกลไก IPC แต่ละรายการได้

องค์ประกอบด้านความปลอดภัยหลายอย่างใช้ร่วมกันในกลไก IPC หากไม่ได้ตั้งใจให้แอปพลิเคชันอื่นใช้กลไก IPC ให้ตั้งค่าแอตทริบิวต์ android:exported เป็น false ในองค์ประกอบไฟล์ Manifest ของคอมโพเนนต์ เช่น องค์ประกอบ <service> ซึ่งมีประโยชน์สำหรับแอปพลิเคชันที่ประกอบด้วยหลายกระบวนการภายใน UID เดียวกัน หรือในกรณีที่คุณตัดสินใจในภายหลังระหว่างการพัฒนาว่าไม่ต้องการเปิดเผยฟังก์ชันการทำงานเป็น IPC แต่ไม่ต้องการเขียนโค้ดใหม่

หากแอปพลิเคชันอื่นๆ เข้าถึง IPC ได้ คุณสามารถใช้นโยบายความปลอดภัย โดยใช้องค์ประกอบ <permission> หาก IPC อยู่ระหว่างแอปของคุณเองและลงนามด้วยคีย์เดียวกัน ให้ใช้สิทธิ์ signature-level ใน android:protectionLevel

Intent

สำหรับกิจกรรมและ Broadcast Receiver นั้น Intent เป็นกลไกที่ต้องการสำหรับ IPC แบบอะซิงโครนัสใน Android คุณอาจใช้ sendBroadcast, sendOrderedBroadcast หรือ Intent ที่ชัดเจนไปยังคอมโพเนนต์ของแอปพลิเคชันที่เฉพาะเจาะจง ทั้งนี้ขึ้นอยู่กับข้อกำหนดของแอปพลิเคชัน เราขอแนะนำให้ใช้ Intent ที่ชัดเจนเพื่อความปลอดภัย

โปรดทราบว่าผู้รับสามารถใช้การออกอากาศที่สั่งซื้อได้ ดังนั้นระบบอาจไม่ส่งการออกอากาศไปยังแอปพลิเคชันทั้งหมด หากคุณส่ง Intent ที่ต้องส่งไปยังผู้รับที่เฉพาะเจาะจง คุณต้องใช้ Intent แบบเจาะจงปลายทาง ซึ่งประกาศผู้รับตามชื่อ

ผู้ส่ง Intent สามารถยืนยันได้ว่าผู้รับมีสิทธิ์โดยการระบุสิทธิ์ที่ไม่ใช่ Null ด้วยการเรียกใช้เมธอด เฉพาะแอปพลิเคชันที่มีสิทธิ์นั้น เท่านั้นที่จะได้รับ Intent หากข้อมูลภายใน Intent การออกอากาศอาจมีความละเอียดอ่อน ให้พิจารณาใช้สิทธิ์เพื่อให้แน่ใจว่าแอปพลิเคชันที่เป็นอันตรายจะไม่สามารถ ลงทะเบียนเพื่อรับข้อความเหล่านั้นโดยไม่มีสิทธิ์ที่เหมาะสม ในกรณีดังกล่าว คุณอาจพิจารณาเรียกใช้ตัวรับโดยตรงแทนที่จะออกอากาศ

บริการ

Service มักใช้เพื่อจัดหาฟังก์ชันการทำงานให้แอปพลิเคชันอื่นๆ ใช้ คลาสบริการแต่ละคลาสต้องมี<service> การประกาศที่สอดคล้องกันในไฟล์ Manifest

โดยค่าเริ่มต้น ระบบจะไม่ส่งออกบริการและแอปพลิเคชันอื่นๆ จะเรียกใช้บริการไม่ได้ อย่างไรก็ตาม หากคุณเพิ่มตัวกรอง Intent ลงในการประกาศบริการ ระบบจะส่งออกตัวกรองดังกล่าวโดยค่าเริ่มต้น คุณควรประกาศแอตทริบิวต์ android:exported อย่างชัดเจนเพื่อให้แน่ใจว่าแอตทริบิวต์ทํางานตามที่คุณต้องการ นอกจากนี้ คุณยังปกป้องบริการได้โดยใช้แอตทริบิวต์ android:permission ด้วยวิธีนี้ แอปพลิเคชันอื่นๆ จะต้องประกาศองค์ประกอบ <uses-permission> ที่สอดคล้องกันในไฟล์ Manifest ของตนเองเพื่อให้สามารถเริ่ม หยุด หรือเชื่อมโยงกับบริการได้

บริการสามารถปกป้องการเรียก IPC แต่ละรายการที่ดำเนินการในบริการนั้นด้วย สิทธิ์ โดยทำได้ด้วยการเรียกใช้ checkCallingPermission() ก่อน ดำเนินการติดตั้งใช้งานการโทร เราขอแนะนำให้ใช้สิทธิ์ที่ประกาศไว้ในไฟล์ Manifest เนื่องจากสิทธิ์เหล่านั้นมีแนวโน้มที่จะถูกละเลยน้อยกว่า

อินเทอร์เฟซ Binder และ Messenger

การใช้ Binder หรือ Messenger เป็นกลไกที่แนะนำสำหรับ IPC รูปแบบ RPC ใน Android โดยมีอินเทอร์เฟซที่กำหนดไว้อย่างดีซึ่งช่วยให้สามารถ ตรวจสอบสิทธิ์ร่วมกันของอุปกรณ์ปลายทางได้หากจำเป็น

เราขอแนะนำให้คุณออกแบบอินเทอร์เฟซของแอปในลักษณะที่ไม่ต้องมีการตรวจสอบสิทธิ์เฉพาะอินเทอร์เฟซ ไม่ได้ประกาศออบเจ็กต์ Binder และ Messenger ภายในไฟล์ Manifest ของแอปพลิเคชัน ดังนั้นคุณจึงไม่สามารถใช้สิทธิ์แบบประกาศกับออบเจ็กต์เหล่านั้นโดยตรงได้ โดยทั่วไปแล้ว Service หรือ Activity จะรับช่วงสิทธิ์ที่ประกาศไว้ในไฟล์ Manifest ของแอปพลิเคชันที่ใช้ หากคุณกำลังสร้างอินเทอร์เฟซที่ ต้องมีการตรวจสอบสิทธิ์และ/หรือการควบคุมการเข้าถึง คุณต้องเพิ่มการควบคุมเหล่านั้นอย่างชัดเจนเป็นโค้ดในอินเทอร์เฟซ Binder หรือ Messenger

หากคุณมีอินเทอร์เฟซที่ต้องใช้การควบคุมการเข้าถึง ให้ใช้ checkCallingPermission() เพื่อยืนยันว่าผู้เรียกมีสิทธิ์ที่จำเป็น หรือไม่ ซึ่งสำคัญอย่างยิ่งก่อนที่จะเข้าถึงบริการในนามของผู้โทร เนื่องจากระบบจะส่งข้อมูลประจำตัวของแอปพลิเคชันไปยังอินเทอร์เฟซอื่นๆ หากคุณเรียกใช้อินเทอร์เฟซที่ Service จัดหาให้ การเรียกใช้ bindService() อาจล้มเหลวหากคุณไม่มีสิทธิ์เข้าถึงบริการที่ระบุ หากต้องการอนุญาตให้กระบวนการภายนอกโต้ตอบกับ แอปของคุณ แต่กระบวนการดังกล่าวไม่มีสิทธิ์ที่จำเป็นในการดำเนินการนี้ คุณสามารถใช้วิธี clearCallingIdentity() ได้ วิธีนี้จะโทรไปยังอินเทอร์เฟซของแอป ราวกับว่าแอปของคุณเป็นผู้โทรเอง ไม่ใช่ผู้โทรภายนอก คุณสามารถกู้คืนสิทธิ์ของผู้โทรได้ในภายหลังด้วยวิธี restoreCallingIdentity()

ดูข้อมูลเพิ่มเติมเกี่ยวกับการทำ IPC กับบริการได้ที่บริการที่เชื่อมโยง

Broadcast Receiver

BroadcastReceiver จัดการคำขอแบบอะซิงโครนัสที่เริ่มต้นโดย Intent

โดยค่าเริ่มต้น ระบบจะส่งออกตัวรับและแอปพลิเคชันอื่นๆ จะเรียกใช้ตัวรับได้ หากBroadcastReceiverมีไว้สำหรับแอปพลิเคชันอื่นๆ คุณอาจต้อง ใช้สิทธิ์ความปลอดภัยกับตัวรับโดยใช้องค์ประกอบ <receiver> ภายในไฟล์ Manifest ของแอปพลิเคชัน ซึ่งจะป้องกันไม่ให้แอปพลิเคชันที่ไม่มีสิทธิ์ที่เหมาะสมส่ง Intent ไปยัง BroadcastReceiver

ความปลอดภัยด้วยโค้ดที่โหลดแบบไดนามิก

เราไม่แนะนำอย่างยิ่งให้โหลดโค้ดจากภายนอก APK ของแอปพลิเคชัน การทำเช่นนี้จะเพิ่มโอกาสที่แอปพลิเคชันจะถูกบุกรุกเนื่องจากการแทรกโค้ดหรือการดัดแปลงโค้ดอย่างมาก นอกจากนี้ ยังเพิ่มความซับซ้อนเกี่ยวกับการจัดการเวอร์ชัน และการทดสอบแอปพลิเคชัน และอาจทำให้ยืนยันลักษณะการทำงานของ แอปพลิเคชันไม่ได้ จึงอาจถูกห้ามในบางสภาพแวดล้อม

หากแอปพลิเคชันโหลดโค้ดแบบไดนามิก สิ่งที่สำคัญที่สุดที่ควรคำนึงถึงคือโค้ดที่โหลดแบบไดนามิกจะทำงานโดยมีสิทธิ์ด้านความปลอดภัยเหมือนกับ APK ของแอปพลิเคชัน ผู้ใช้ตัดสินใจติดตั้งแอปพลิเคชันของคุณโดยอิงตามตัวตนของคุณ และผู้ใช้คาดหวังว่าคุณจะจัดหาโค้ดที่เรียกใช้ภายในแอปพลิเคชัน ซึ่งรวมถึงโค้ดที่โหลดแบบไดนามิก

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

ความปลอดภัยในเครื่องเสมือน

Dalvik คือเครื่องเสมือน (VM) รันไทม์ของ Android Dalvik สร้างขึ้นมาสำหรับ Android โดยเฉพาะ แต่ข้อกังวลหลายอย่างเกี่ยวกับโค้ดที่ปลอดภัยในเครื่องเสมือนอื่นๆ ก็ใช้กับ Android ได้เช่นกัน โดยทั่วไปแล้ว คุณไม่จำเป็นต้องกังวล เกี่ยวกับปัญหาด้านความปลอดภัยที่เกี่ยวข้องกับเครื่องเสมือน แอปพลิเคชันของคุณทำงานในสภาพแวดล้อมแซนด์บ็อกซ์ที่ปลอดภัย ดังนั้นกระบวนการอื่นๆ ในระบบจึงเข้าถึงโค้ดหรือข้อมูลส่วนตัวของคุณไม่ได้

หากสนใจดูข้อมูลเพิ่มเติมเกี่ยวกับความปลอดภัยของเครื่องเสมือน โปรดศึกษาเอกสารที่มีอยู่เกี่ยวกับเรื่องนี้ แหล่งข้อมูลที่ได้รับความนิยมมากที่สุด 2 แหล่ง ได้แก่

เอกสารนี้มุ่งเน้นที่ส่วนต่างๆ ที่เฉพาะเจาะจงสำหรับ Android หรือแตกต่างจากสภาพแวดล้อม VM อื่นๆ สำหรับนักพัฒนาแอปที่มีประสบการณ์ในการเขียนโปรแกรม VM ในสภาพแวดล้อมอื่นๆ มีปัญหา 2 อย่างที่อาจแตกต่างกันเกี่ยวกับการเขียนแอปสำหรับ Android ดังนี้

  • เครื่องเสมือนบางเครื่อง เช่น JVM หรือ .NET Runtime ทำหน้าที่เป็นขอบเขตด้านความปลอดภัย โดยแยกโค้ดออกจากความสามารถของระบบปฏิบัติการพื้นฐาน ใน Android, Dalvik VM ไม่ใช่ขอบเขตด้านความปลอดภัย - แซนด์บ็อกซ์ของแอปพลิเคชัน ได้รับการติดตั้งใช้งานที่ระดับระบบปฏิบัติการ ดังนั้น Dalvik จึงทำงานร่วมกับโค้ดแบบเนทีฟใน แอปพลิเคชันเดียวกันได้โดยไม่มีข้อจำกัดด้านความปลอดภัย
  • เนื่องจากอุปกรณ์เคลื่อนที่มีพื้นที่เก็บข้อมูลจำกัด นักพัฒนาแอปจึงมักต้องการสร้างแอปพลิเคชันแบบแยกส่วนและใช้การโหลดคลาสแบบไดนามิก เมื่อดำเนินการนี้ ให้พิจารณาทั้งแหล่งที่มาที่คุณดึงตรรกะของแอปพลิเคชันและตำแหน่งที่คุณจัดเก็บไว้ในเครื่อง ห้ามใช้การโหลดคลาสแบบไดนามิกจากแหล่งที่มาที่ ไม่ได้รับการยืนยัน เช่น แหล่งที่มาของเครือข่ายที่ไม่ปลอดภัยหรือที่เก็บข้อมูลภายนอก เนื่องจากโค้ดดังกล่าวอาจได้รับการแก้ไขให้มีลักษณะการทำงานที่เป็นอันตราย

ความปลอดภัยในโค้ดแบบเนทีฟ

โดยทั่วไป เราขอแนะนำให้ใช้ Android SDK ในการพัฒนาแอปพลิเคชัน แทนการใช้โค้ดแบบเนทีฟกับ Android NDK แอปพลิเคชันที่สร้างด้วยโค้ดแบบเนทีฟมีความซับซ้อนมากกว่า พกพาได้น้อยกว่า และมีแนวโน้มที่จะมีข้อผิดพลาดเกี่ยวกับการเสียหายของหน่วยความจำทั่วไป เช่น การบัฟเฟอร์เกินขอบเขตที่กำหนด

Android สร้างขึ้นโดยใช้เคอร์เนล Linux และการทำความคุ้นเคยกับแนวทางปฏิบัติแนะนำด้านความปลอดภัยในการพัฒนา Linux จะมีประโยชน์อย่างยิ่งหากคุณใช้โค้ดดั้งเดิม แนวทางปฏิบัติในการรักษาความปลอดภัยของ Linux อยู่นอกขอบเขตของเอกสารนี้ แต่แหล่งข้อมูลยอดนิยมอย่างหนึ่งคือ Secure Programming HOWTO - Creating Secure Software

ความแตกต่างที่สำคัญระหว่าง Android กับสภาพแวดล้อม Linux ส่วนใหญ่คือ แซนด์บ็อกซ์ของแอปพลิเคชัน ใน Android แอปพลิเคชันทั้งหมดจะทำงานในแซนด์บ็อกซ์ของแอปพลิเคชัน รวมถึงแอปพลิเคชันที่เขียนด้วยโค้ดแบบเนทีฟ วิธีที่ดีในการทำความเข้าใจสำหรับนักพัฒนาแอปที่คุ้นเคยกับ Linux คือการทราบว่าแอปพลิเคชันทุกแอปจะได้รับ ตัวระบุผู้ใช้ (UID) ที่ไม่ซ้ำกันพร้อมสิทธิ์ที่จำกัดมาก ซึ่งจะอธิบายโดยละเอียดเพิ่มเติมในภาพรวมความปลอดภัยของ Android และคุณควร คุ้นเคยกับสิทธิ์ของแอปพลิเคชันแม้ว่าจะใช้โค้ดแบบเนทีฟก็ตาม