หมวดหมู่ OWASP: MASVS-CODE: คุณภาพโค้ด
ภาพรวม
Android มีเฟรมเวิร์กอันทรงประสิทธิภาพที่เรียกว่าคลิปบอร์ดสําหรับการคัดลอกและวางข้อมูลระหว่างแอปพลิเคชัน การใช้งานฟีเจอร์นี้อย่างไม่เหมาะสมอาจทำให้ข้อมูลที่เกี่ยวข้องกับผู้ใช้ถูกเปิดเผยต่อผู้ไม่ประสงค์ดีหรือแอปพลิเคชันที่ไม่ได้รับอนุญาต
ความเสี่ยงที่เฉพาะเจาะจงซึ่งเชื่อมโยงกับการเปิดเผยข้อมูลในคลิปบอร์ดจะขึ้นอยู่กับลักษณะของแอปพลิเคชันและข้อมูลส่วนบุคคลที่ระบุตัวบุคคลนั้นได้ (PII) ที่แอปพลิเคชันจัดการ แอปพลิเคชันทางการเงินจะได้รับผลกระทบอย่างมาก เนื่องจากอาจเปิดเผยข้อมูลการชำระเงิน หรือแอปที่จัดการรหัสการตรวจสอบสิทธิ์แบบ 2 ปัจจัย (2FA)
เวกเตอร์การโจมตีที่อาจใช้ประโยชน์เพื่อลักลอบนำข้อมูลในคลิปบอร์ดออกจะแตกต่างกันไปตามเวอร์ชัน Android ดังนี้
- Android เวอร์ชันเก่ากว่า Android 10 (API ระดับ 29) อนุญาตให้แอปพลิเคชันที่ทำงานอยู่เบื้องหลังเข้าถึงข้อมูลคลิปบอร์ดของแอปที่ทำงานอยู่เบื้องหน้า ซึ่งอาจทำให้ผู้ไม่ประสงค์ดีเข้าถึงข้อมูลที่คัดลอกไว้ได้โดยตรง
- ตั้งแต่ Android 12 เป็นต้นไป (API ระดับ 31) ทุกครั้งที่แอปพลิเคชันเข้าถึงข้อมูลในคลิปบอร์ดและวางข้อมูลนั้น ระบบจะแสดงข้อความแจ้งให้ผู้ใช้ทราบ ซึ่งทำให้การโจมตีถูกสังเกตได้ยากขึ้น นอกจากนี้ Android ยังรองรับ Flag พิเศษ
ClipDescription.EXTRA_IS_SENSITIVE
หรือandroid.content.extra.IS_SENSITIVE
เพื่อปกป้อง PII ด้วย ซึ่งช่วยให้นักพัฒนาแอปสร้างความสับสนให้กับตัวอย่างเนื้อหาในคลิปบอร์ดภายใน GUI ของแป้นพิมพ์ได้ เพื่อป้องกันไม่ให้แอปพลิเคชันที่เป็นอันตรายแสดงข้อมูลที่คัดลอกในรูปแบบข้อความธรรมดาและอาจขโมยข้อมูลได้ การไม่ใช้ Flag ใด Flag หนึ่งข้างต้นอาจทำให้ผู้โจมตีสามารถลักลอบนำข้อมูลที่ละเอียดอ่อนซึ่งคัดลอกไปยังคลิปบอร์ดไปใช้ได้ด้วยการแอบดูจากด้านหลังหรือผ่านแอปพลิเคชันที่เป็นอันตรายซึ่งถ่ายภาพหน้าจอหรือบันทึกวิดีโอกิจกรรมของผู้ใช้ที่ถูกต้องขณะทำงานอยู่เบื้องหลัง
ผลกระทบ
การใช้การจัดการคลิปบอร์ดที่ไม่เหมาะสมอาจส่งผลให้ผู้ไม่ประสงค์ดีขโมยข้อมูลทางการเงินหรือข้อมูลที่ละเอียดอ่อนที่เกี่ยวข้องกับผู้ใช้ ซึ่งอาจช่วยให้ผู้โจมตีดำเนินการต่อได้ เช่น แคมเปญฟิชชิงหรือการโจรกรรมข้อมูลประจำตัว
การลดปัญหา
แจ้งข้อมูลที่ละเอียดอ่อน
โซลูชันนี้ใช้เพื่อสร้างความสับสนให้กับการแสดงตัวอย่างเนื้อหาในคลิปบอร์ดภายใน GUI ของแป้นพิมพ์ ข้อมูลที่ละเอียดอ่อนซึ่งคัดลอกได้ เช่น รหัสผ่านหรือข้อมูลบัตรเครดิต ควรแจ้งว่าไม่เหมาะสมด้วย ClipDescription.EXTRA_IS_SENSITIVE
หรือ android.content.extra.IS_SENSITIVE
ก่อนเรียกใช้ ClipboardManager.setPrimaryClip()
Kotlin
// If your app is compiled with the API level 33 SDK or higher.
clipData.apply {
description.extras = PersistableBundle().apply {
putBoolean(ClipDescription.EXTRA_IS_SENSITIVE, true)
}
}
// If your app is compiled with API level 32 SDK or lower.
clipData.apply {
description.extras = PersistableBundle().apply {
putBoolean("android.content.extra.IS_SENSITIVE", true)
}
}
Java
// If your app is compiled with the API level 33 SDK or higher.
PersistableBundle extras = new PersistableBundle();
extras.putBoolean(ClipDescription.EXTRA_IS_SENSITIVE, true);
clipData.getDescription().setExtras(extras);
// If your app is compiled with API level 32 SDK or lower.
PersistableBundle extras = new PersistableBundle();
extras.putBoolean("android.content.extra.IS_SENSITIVE", true);
clipData.getDescription().setExtras(extras);
บังคับใช้ Android เวอร์ชันล่าสุด
การบังคับให้แอปทำงานใน Android เวอร์ชันที่ใหม่กว่าหรือเท่ากับ Android 10 (API 29) จะป้องกันไม่ให้กระบวนการทำงานเบื้องหลังเข้าถึงข้อมูลคลิปบอร์ดในแอปพลิเคชันเบื้องหน้า
หากต้องการบังคับให้แอปทำงานใน Android 10 (API 29) ขึ้นไปเท่านั้น ให้ตั้งค่าต่อไปนี้สำหรับการตั้งค่าเวอร์ชันในไฟล์บิลด์ Gradle ภายในโปรเจ็กต์ใน Android Studio
Groovy
android {
namespace 'com.example.testapp'
compileSdk [SDK_LATEST_VERSION]
defaultConfig {
applicationId "com.example.testapp"
minSdk 29
targetSdk [SDK_LATEST_VERSION]
versionCode 1
versionName "1.0"
...
}
...
}
...
Kotlin
android {
namespace = "com.example.testapp"
compileSdk = [SDK_LATEST_VERSION]
defaultConfig {
applicationId = "com.example.testapp"
minSdk = 29
targetSdk = [SDK_LATEST_VERSION]
versionCode = 1
versionName = "1.0"
...
}
...
}
...
ลบเนื้อหาในคลิปบอร์ดหลังจากผ่านไประยะเวลาหนึ่ง
หากแอปพลิเคชันมีไว้เพื่อใช้งานใน Android เวอร์ชันที่ต่ำกว่า Android 10 (API ระดับ 29) แอปพลิเคชันใดก็ตามที่ทำงานอยู่เบื้องหลังจะเข้าถึงข้อมูลในคลิปบอร์ดได้ หากต้องการลดความเสี่ยงนี้ คุณควรใช้ฟังก์ชันที่ล้างข้อมูลที่คัดลอกไปยังคลิปบอร์ดหลังจากผ่านไประยะเวลาหนึ่ง ฟังก์ชันนี้จะทำงานโดยอัตโนมัติตั้งแต่ Android 13 (API ระดับ 33) เป็นต้นไป สําหรับ Android เวอร์ชันเก่า คุณสามารถลบได้โดยใส่ข้อมูลโค้ดต่อไปนี้ไว้ในโค้ดของแอปพลิเคชัน
Kotlin
//The Executor makes this task Asynchronous so that the UI continues being responsive
backgroundExecutor.schedule({
//Creates a clip object with the content of the Clipboard
val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
val clip = clipboard.primaryClip
//If SDK version is higher or equal to 28, it deletes Clipboard data with clearPrimaryClip()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
clipboard.clearPrimaryClip()
} else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
//If SDK version is lower than 28, it will replace Clipboard content with an empty value
val newEmptyClip = ClipData.newPlainText("EmptyClipContent", "")
clipboard.setPrimaryClip(newEmptyClip)
}
//The delay after which the Clipboard is cleared, measured in seconds
}, 5, TimeUnit.SECONDS)
Java
//The Executor makes this task Asynchronous so that the UI continues being responsive
ScheduledExecutorService backgroundExecutor = Executors.newSingleThreadScheduledExecutor();
backgroundExecutor.schedule(new Runnable() {
@Override
public void run() {
//Creates a clip object with the content of the Clipboard
ClipboardManager clipboard = (ClipboardManager)getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = clipboard.getPrimaryClip();
//If SDK version is higher or equal to 28, it deletes Clipboard data with clearPrimaryClip()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
clipboard.clearPrimaryClip();
//If SDK version is lower than 28, it will replace Clipboard content with an empty value
} else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
ClipData newEmptyClip = ClipData.newPlainText("EmptyClipContent", "");
clipboard.setPrimaryClip(newEmptyClip);
}
//The delay after which the Clipboard is cleared, measured in seconds
}, 5, TimeUnit.SECONDS);
แหล่งข้อมูล
- เฟรมเวิร์กคลิปบอร์ด
- การแจ้งเตือนของระบบที่แสดงเมื่อแอปเข้าถึงข้อมูลคลิปบอร์ด
- เพิ่มเนื้อหาที่ละเอียดอ่อนลงในคลิปบอร์ด
- การเปลี่ยนแปลงด้านความเป็นส่วนตัวใน Android 10
- ตั้งค่าข้อมูลเวอร์ชันแอป