OWASP Mobile Top 10:2024
คู่มือ 10 หมวดความเสี่ยงใน OWASP Mobile Top 10:2024 ฉบับปัจจุบัน สำหรับ Android, iOS และบริการที่แอปพึ่งพา
ฉบับ 2024; ใช้ชื่อหมวดความเสี่ยงตามเอกสาร OWASP ทางการ
M1
Improper Credential Usage
Improper Credential Usage คือแอปมือถือฝัง, เก็บ, ส่ง หรือใช้ password, API key, token หรือ session อย่างไม่ปลอดภัย เช่น hardcode secret ใน binary หรือเก็บรหัสผ่านในพื้นที่ทั่วไปของเครื่อง เมื่อแอปถูก reverse engineer หรือโทรศัพท์สูญหาย ผู้โจมตีอาจนำข้อมูลยืนยันตัวตนไปใช้กับ backend ได้.
| สิ่งที่อาจผิดพลาด | secret token API key หรือรหัสผ่านถูกฝัง ใช้ซ้ำ เปิดเผย หรือจัดการโดยไม่มีวงจรชีวิตที่เหมาะสม |
|---|---|
| ผลกระทบต่อธุรกิจ | แพ็กเกจแอปที่ถูกวิเคราะห์หรือ token ที่รั่วไหลอาจให้สิทธิ์เข้าถึง backend หรือฟังก์ชันที่ป้องกันอย่างต่อเนื่อง |
| จุดควบคุมแรกที่ควรตรวจ | ไม่เก็บ secret ระยะยาวไว้ในฝั่ง client |
ผู้โจมตี เหยื่อ แอปพลิเคชัน จุดควบคุม

ภาพเปรียบเทียบเส้นทางที่ไม่ปลอดภัยกับจุดควบคุมที่ตัดเส้นทางนั้น กดภาพเพื่อดูขนาดเต็ม.
ผลกระทบที่ควรพิจารณา
แพ็กเกจแอปที่ถูกวิเคราะห์หรือ token ที่รั่วไหลอาจให้สิทธิ์เข้าถึง backend หรือฟังก์ชันที่ป้องกันอย่างต่อเนื่อง
แนวทางลดความเสี่ยง
- ไม่เก็บ secret ระยะยาวไว้ในฝั่ง client
- ใช้ credential ที่จำกัดขอบเขต เพิกถอนได้ และหมุนเวียนได้
- ปกป้องจุดกรอกและเส้นทางส่ง credential
ตัวอย่าง Android ด้วย Kotlin
ตัวอย่างที่มีช่องโหว่
import android.content.Intent
import android.net.Uri
import androidx.appcompat.app.AppCompatActivity
class RedirectActivity : AppCompatActivity() {
fun openRedirect(intent: Intent) {
val rawTarget = intent.data?.getQueryParameter("redirect") ?: return
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(rawTarget)))
}
}ตัวอย่างที่แก้ไขแล้ว
import android.content.Intent
import android.net.Uri
import androidx.browser.customtabs.CustomTabsIntent
import androidx.appcompat.app.AppCompatActivity
class RedirectActivity : AppCompatActivity() {
private val allowedHosts = setOf("app.example.com")
fun openRedirect(intent: Intent) {
val rawTarget = intent.data?.getQueryParameter("redirect") ?: return
val target = Uri.parse(rawTarget)
if (target.scheme != "https" || target.host !in allowedHosts) return
CustomTabsIntent.Builder().build().launchUrl(this, target)
}
}ตัวอย่าง iOS ด้วย Swift
ตัวอย่างที่มีช่องโหว่
import UIKit
final class RedirectViewController: UIViewController {
func openRedirect(rawTarget: String) {
guard let target = URL(string: rawTarget) else { return }
UIApplication.shared.open(target)
}
}ตัวอย่างที่แก้ไขแล้ว
import SafariServices
import UIKit
final class RedirectViewController: UIViewController {
private let allowedHosts: Set<String> = ["app.example.com"]
func openRedirect(rawTarget: String) {
guard let target = URL(string: rawTarget),
target.scheme == "https",
let host = target.host,
allowedHosts.contains(host) else { return }
let browser = SFSafariViewController(url: target)
present(browser, animated: true)
}
}M2
Inadequate Supply Chain Security
Inadequate Supply Chain Security คือแอป, SDK, dependency, ระบบ build หรือการเซ็น package ไม่ได้รับการควบคุมแหล่งที่มาและความถูกต้องเพียงพอ SDK ภายนอกที่ถูกเปลี่ยน, pipeline ที่ถูกยึด หรือ signing key รั่ว อาจทำให้แอปที่ติดตั้งบนเครื่องผู้ใช้ทำสิ่งที่ทีมไม่ได้ตั้งใจ.
| สิ่งที่อาจผิดพลาด | SDK มือถือ build plugin ระบบลงนาม และ dependency สำหรับแจกจ่ายไม่ได้รับการกำกับดูแลเพียงพอ |
|---|---|
| ผลกระทบต่อธุรกิจ | SDK หรือ release pipeline ที่ถูกโจมตีอาจเพิ่มการติดตาม เปิดเผยข้อมูล หรือเปลี่ยนพฤติกรรมของแอป |
| จุดควบคุมแรกที่ควรตรวจ | จัดทำบัญชี SDK ภายนอกและ data flow ของแต่ละตัว |
ผู้โจมตี เหยื่อ แอปพลิเคชัน จุดควบคุม

ภาพเปรียบเทียบเส้นทางที่ไม่ปลอดภัยกับจุดควบคุมที่ตัดเส้นทางนั้น กดภาพเพื่อดูขนาดเต็ม.
ผลกระทบที่ควรพิจารณา
SDK หรือ release pipeline ที่ถูกโจมตีอาจเพิ่มการติดตาม เปิดเผยข้อมูล หรือเปลี่ยนพฤติกรรมของแอป
แนวทางลดความเสี่ยง
- จัดทำบัญชี SDK ภายนอกและ data flow ของแต่ละตัว
- จำกัดและตรวจสอบสิทธิ์ในการลงนามและ release
- ตรวจสอบที่มา ความถูกต้อง และประกาศอัปเดตของแพ็กเกจ
ตัวอย่าง Android ด้วย Kotlin
ตัวอย่างที่มีช่องโหว่
import android.content.Intent
import android.net.Uri
import androidx.appcompat.app.AppCompatActivity
class RedirectActivity : AppCompatActivity() {
fun openRedirect(intent: Intent) {
val rawTarget = intent.data?.getQueryParameter("redirect") ?: return
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(rawTarget)))
}
}ตัวอย่างที่แก้ไขแล้ว
import android.content.Intent
import android.net.Uri
import androidx.browser.customtabs.CustomTabsIntent
import androidx.appcompat.app.AppCompatActivity
class RedirectActivity : AppCompatActivity() {
private val allowedHosts = setOf("app.example.com")
fun openRedirect(intent: Intent) {
val rawTarget = intent.data?.getQueryParameter("redirect") ?: return
val target = Uri.parse(rawTarget)
if (target.scheme != "https" || target.host !in allowedHosts) return
CustomTabsIntent.Builder().build().launchUrl(this, target)
}
}ตัวอย่าง iOS ด้วย Swift
ตัวอย่างที่มีช่องโหว่
import UIKit
final class RedirectViewController: UIViewController {
func openRedirect(rawTarget: String) {
guard let target = URL(string: rawTarget) else { return }
UIApplication.shared.open(target)
}
}ตัวอย่างที่แก้ไขแล้ว
import SafariServices
import UIKit
final class RedirectViewController: UIViewController {
private let allowedHosts: Set<String> = ["app.example.com"]
func openRedirect(rawTarget: String) {
guard let target = URL(string: rawTarget),
target.scheme == "https",
let host = target.host,
allowedHosts.contains(host) else { return }
let browser = SFSafariViewController(url: target)
present(browser, animated: true)
}
}M3
Insecure Authentication/Authorization
Insecure Authentication/Authorization คือแอปยืนยันว่าใครเป็นผู้ใช้หรืออนุญาตให้ทำอะไรไม่ถูกต้อง เช่น ไม่ตรวจ token ให้ครบ, เชื่อ role ที่ส่งจาก client, หรือปล่อย session ใช้ต่อหลัง logout ผู้โจมตีอาจยึดบัญชี ใช้ข้อมูลของผู้อื่น หรือเรียกฟังก์ชันที่ควรจำกัดเฉพาะบทบาทได้.
| สิ่งที่อาจผิดพลาด | แอปหรือ backend ยอมรับการพิสูจน์ตัวตน การจัดการ session หรือการตัดสินใจเรื่องสิทธิ์ที่อ่อนแอ |
|---|---|
| ผลกระทบต่อธุรกิจ | ผู้ใช้บนอุปกรณ์หรือผู้โจมตีจากระยะไกลอาจเข้าถึงบัญชี ฟีเจอร์ หรือชุดข้อมูลของผู้อื่นได้ |
| จุดควบคุมแรกที่ควรตรวจ | ตรวจสิทธิ์คำขอบน backend ไม่ใช่เฉพาะในแอป |
ผู้โจมตี เหยื่อ แอปพลิเคชัน จุดควบคุม

ภาพเปรียบเทียบเส้นทางที่ไม่ปลอดภัยกับจุดควบคุมที่ตัดเส้นทางนั้น กดภาพเพื่อดูขนาดเต็ม.
ผลกระทบที่ควรพิจารณา
ผู้ใช้บนอุปกรณ์หรือผู้โจมตีจากระยะไกลอาจเข้าถึงบัญชี ฟีเจอร์ หรือชุดข้อมูลของผู้อื่นได้
แนวทางลดความเสี่ยง
- ตรวจสิทธิ์คำขอบน backend ไม่ใช่เฉพาะในแอป
- ใช้ session ที่ปลอดภัยและ MFA ตามระดับความเสี่ยง
- ทดสอบ deep link component ของแอป และสิทธิ์เข้าถึงออบเจ็กต์บน backend
ตัวอย่าง Android ด้วย Kotlin
ตัวอย่างที่มีช่องโหว่
import android.content.Intent
import android.net.Uri
import androidx.appcompat.app.AppCompatActivity
class RedirectActivity : AppCompatActivity() {
fun openRedirect(intent: Intent) {
val rawTarget = intent.data?.getQueryParameter("redirect") ?: return
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(rawTarget)))
}
}ตัวอย่างที่แก้ไขแล้ว
import android.content.Intent
import android.net.Uri
import androidx.browser.customtabs.CustomTabsIntent
import androidx.appcompat.app.AppCompatActivity
class RedirectActivity : AppCompatActivity() {
private val allowedHosts = setOf("app.example.com")
fun openRedirect(intent: Intent) {
val rawTarget = intent.data?.getQueryParameter("redirect") ?: return
val target = Uri.parse(rawTarget)
if (target.scheme != "https" || target.host !in allowedHosts) return
CustomTabsIntent.Builder().build().launchUrl(this, target)
}
}ตัวอย่าง iOS ด้วย Swift
ตัวอย่างที่มีช่องโหว่
import UIKit
final class RedirectViewController: UIViewController {
func openRedirect(rawTarget: String) {
guard let target = URL(string: rawTarget) else { return }
UIApplication.shared.open(target)
}
}ตัวอย่างที่แก้ไขแล้ว
import SafariServices
import UIKit
final class RedirectViewController: UIViewController {
private let allowedHosts: Set<String> = ["app.example.com"]
func openRedirect(rawTarget: String) {
guard let target = URL(string: rawTarget),
target.scheme == "https",
let host = target.host,
allowedHosts.contains(host) else { return }
let browser = SFSafariViewController(url: target)
present(browser, animated: true)
}
}M4
Insufficient Input/Output Validation
Insufficient Input/Output Validation คือแอปเชื่อ deep link, QR, intent, file, response จาก server หรือข้อมูลที่แสดงผลโดยไม่ตรวจรูปแบบ แหล่งที่มา และขอบเขตก่อนใช้งาน ข้อมูลที่ดัดแปลงจึงอาจพาแอปเปิดปลายทางที่ไม่ปลอดภัย, ทำงานผิด flow หรือส่งข้อมูลกลับออกไปผิดที่.
| สิ่งที่อาจผิดพลาด | ข้อมูลที่ข้ามขอบเขตระหว่างแอป อุปกรณ์ backend เบราว์เซอร์ หรือบุคคลที่สามได้รับความเชื่อถือโดยตรวจสอบไม่เพียงพอ |
|---|---|
| ผลกระทบต่อธุรกิจ | เนื้อหาที่เป็นอันตรายอาจเปลี่ยน flow ของแอป ถูกแสดงผลอย่างไม่ปลอดภัย หรือทำให้ backend ดำเนินการที่ไม่ปลอดภัย |
| จุดควบคุมแรกที่ควรตรวจ | ตรวจสอบข้อมูลภายนอกทั้งหมดที่ทุกขอบเขตความเชื่อถือ |
ผู้โจมตี เหยื่อ แอปพลิเคชัน จุดควบคุม

ภาพเปรียบเทียบเส้นทางที่ไม่ปลอดภัยกับจุดควบคุมที่ตัดเส้นทางนั้น กดภาพเพื่อดูขนาดเต็ม.
ผลกระทบที่ควรพิจารณา
เนื้อหาที่เป็นอันตรายอาจเปลี่ยน flow ของแอป ถูกแสดงผลอย่างไม่ปลอดภัย หรือทำให้ backend ดำเนินการที่ไม่ปลอดภัย
แนวทางลดความเสี่ยง
- ตรวจสอบข้อมูลภายนอกทั้งหมดที่ทุกขอบเขตความเชื่อถือ
- encode ข้อมูลออกให้เหมาะกับบริบทการแสดงผล
- ใช้ contract ที่มีชนิดข้อมูลและปฏิเสธ field ที่ไม่คาดคิด
ตัวอย่าง Android ด้วย Kotlin
ตัวอย่างที่มีช่องโหว่
import android.content.Intent
import android.net.Uri
import androidx.appcompat.app.AppCompatActivity
class RedirectActivity : AppCompatActivity() {
fun openRedirect(intent: Intent) {
val rawTarget = intent.data?.getQueryParameter("redirect") ?: return
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(rawTarget)))
}
}ตัวอย่างที่แก้ไขแล้ว
import android.content.Intent
import android.net.Uri
import androidx.browser.customtabs.CustomTabsIntent
import androidx.appcompat.app.AppCompatActivity
class RedirectActivity : AppCompatActivity() {
private val allowedHosts = setOf("app.example.com")
fun openRedirect(intent: Intent) {
val rawTarget = intent.data?.getQueryParameter("redirect") ?: return
val target = Uri.parse(rawTarget)
if (target.scheme != "https" || target.host !in allowedHosts) return
CustomTabsIntent.Builder().build().launchUrl(this, target)
}
}ตัวอย่าง iOS ด้วย Swift
ตัวอย่างที่มีช่องโหว่
import UIKit
final class RedirectViewController: UIViewController {
func openRedirect(rawTarget: String) {
guard let target = URL(string: rawTarget) else { return }
UIApplication.shared.open(target)
}
}ตัวอย่างที่แก้ไขแล้ว
import SafariServices
import UIKit
final class RedirectViewController: UIViewController {
private let allowedHosts: Set<String> = ["app.example.com"]
func openRedirect(rawTarget: String) {
guard let target = URL(string: rawTarget),
target.scheme == "https",
let host = target.host,
allowedHosts.contains(host) else { return }
let browser = SFSafariViewController(url: target)
present(browser, animated: true)
}
}M5
Insecure Communication
Insecure Communication คือข้อมูลระหว่างแอปกับบริการไม่ได้รับการปกป้องจากการดักฟังหรือแก้ไขอย่างพอเพียง เช่น ยอมรับ certificate ที่ไม่น่าเชื่อถือ, ใช้ HTTP, ตรวจ TLS ไม่ครบ หรือส่งข้อมูลลับผ่านช่องทางอื่นที่ไม่ปลอดภัย ผู้โจมตีบนเครือข่ายเดียวกันจึงอาจอ่านข้อความหรือแทรกข้อมูลได้.
| สิ่งที่อาจผิดพลาด | ทราฟฟิกเครือข่าย การจัดการใบรับรอง หรือการเลือกช่องทางสื่อสารไม่ปกป้องข้อมูลระหว่างส่งอย่างเพียงพอ |
|---|---|
| ผลกระทบต่อธุรกิจ | เครือข่ายที่ไม่ปลอดภัยหรือถูกโจมตีอาจดักดู แก้ไข หรือเปลี่ยนเส้นทางการสื่อสารที่สำคัญ |
| จุดควบคุมแรกที่ควรตรวจ | บังคับใช้ TLS ปัจจุบันสำหรับการเชื่อมต่อสำคัญ |
ผู้โจมตี เหยื่อ แอปพลิเคชัน จุดควบคุม

ภาพเปรียบเทียบเส้นทางที่ไม่ปลอดภัยกับจุดควบคุมที่ตัดเส้นทางนั้น กดภาพเพื่อดูขนาดเต็ม.
ผลกระทบที่ควรพิจารณา
เครือข่ายที่ไม่ปลอดภัยหรือถูกโจมตีอาจดักดู แก้ไข หรือเปลี่ยนเส้นทางการสื่อสารที่สำคัญ
แนวทางลดความเสี่ยง
- บังคับใช้ TLS ปัจจุบันสำหรับการเชื่อมต่อสำคัญ
- ตรวจสอบ certificate และหลีกเลี่ยงพฤติกรรมที่เชื่อถือทุกใบรับรอง
- ลดข้อมูลสำคัญใน request และข้อมูลวินิจฉัย
ตัวอย่าง Android ด้วย Kotlin
ตัวอย่างที่มีช่องโหว่
import android.content.Intent
import android.net.Uri
import androidx.appcompat.app.AppCompatActivity
class RedirectActivity : AppCompatActivity() {
fun openRedirect(intent: Intent) {
val rawTarget = intent.data?.getQueryParameter("redirect") ?: return
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(rawTarget)))
}
}ตัวอย่างที่แก้ไขแล้ว
import android.content.Intent
import android.net.Uri
import androidx.browser.customtabs.CustomTabsIntent
import androidx.appcompat.app.AppCompatActivity
class RedirectActivity : AppCompatActivity() {
private val allowedHosts = setOf("app.example.com")
fun openRedirect(intent: Intent) {
val rawTarget = intent.data?.getQueryParameter("redirect") ?: return
val target = Uri.parse(rawTarget)
if (target.scheme != "https" || target.host !in allowedHosts) return
CustomTabsIntent.Builder().build().launchUrl(this, target)
}
}ตัวอย่าง iOS ด้วย Swift
ตัวอย่างที่มีช่องโหว่
import UIKit
final class RedirectViewController: UIViewController {
func openRedirect(rawTarget: String) {
guard let target = URL(string: rawTarget) else { return }
UIApplication.shared.open(target)
}
}ตัวอย่างที่แก้ไขแล้ว
import SafariServices
import UIKit
final class RedirectViewController: UIViewController {
private let allowedHosts: Set<String> = ["app.example.com"]
func openRedirect(rawTarget: String) {
guard let target = URL(string: rawTarget),
target.scheme == "https",
let host = target.host,
allowedHosts.contains(host) else { return }
let browser = SFSafariViewController(url: target)
present(browser, animated: true)
}
}M6
Inadequate Privacy Controls
Inadequate Privacy Controls คือแอปเก็บ ใช้ เปิดเผย หรือเก็บรักษาข้อมูลส่วนบุคคลเกินวัตถุประสงค์หรือโดยไม่มีการควบคุมที่เข้าใจได้ เช่น ขอ permission เกินจำเป็น, ส่ง analytics ที่ระบุตัวบุคคลได้ หรือไม่มีทางให้ผู้ใช้จัดการ consent ความเสี่ยงครอบคลุมทั้งผู้ใช้ ความเชื่อมั่น และข้อกำหนดด้านข้อมูลส่วนบุคคล.
| สิ่งที่อาจผิดพลาด | แอปรวบรวม แชร์ เก็บรักษา หรือเปิดเผยข้อมูลส่วนบุคคลเกินกว่าวัตถุประสงค์ที่แจ้งและจำเป็น |
|---|---|
| ผลกระทบต่อธุรกิจ | ผู้ใช้อาจสูญเสียการควบคุมข้อมูลส่วนบุคคลผ่าน telemetry permission analytics หรือการแบ่งปันกับบุคคลที่สาม |
| จุดควบคุมแรกที่ควรตรวจ | ทำแผนที่การเก็บข้อมูลส่วนบุคคลและผู้รับข้อมูล |
ผู้โจมตี เหยื่อ แอปพลิเคชัน จุดควบคุม

ภาพเปรียบเทียบเส้นทางที่ไม่ปลอดภัยกับจุดควบคุมที่ตัดเส้นทางนั้น กดภาพเพื่อดูขนาดเต็ม.
ผลกระทบที่ควรพิจารณา
ผู้ใช้อาจสูญเสียการควบคุมข้อมูลส่วนบุคคลผ่าน telemetry permission analytics หรือการแบ่งปันกับบุคคลที่สาม
แนวทางลดความเสี่ยง
- ทำแผนที่การเก็บข้อมูลส่วนบุคคลและผู้รับข้อมูล
- ขอเฉพาะ permission ที่จำเป็นในเวลาที่เหมาะสม
- ใช้การควบคุมการเก็บรักษา ความยินยอม และการลบข้อมูล
ตัวอย่าง Android ด้วย Kotlin
ตัวอย่างที่มีช่องโหว่
import android.content.Intent
import android.net.Uri
import androidx.appcompat.app.AppCompatActivity
class RedirectActivity : AppCompatActivity() {
fun openRedirect(intent: Intent) {
val rawTarget = intent.data?.getQueryParameter("redirect") ?: return
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(rawTarget)))
}
}ตัวอย่างที่แก้ไขแล้ว
import android.content.Intent
import android.net.Uri
import androidx.browser.customtabs.CustomTabsIntent
import androidx.appcompat.app.AppCompatActivity
class RedirectActivity : AppCompatActivity() {
private val allowedHosts = setOf("app.example.com")
fun openRedirect(intent: Intent) {
val rawTarget = intent.data?.getQueryParameter("redirect") ?: return
val target = Uri.parse(rawTarget)
if (target.scheme != "https" || target.host !in allowedHosts) return
CustomTabsIntent.Builder().build().launchUrl(this, target)
}
}ตัวอย่าง iOS ด้วย Swift
ตัวอย่างที่มีช่องโหว่
import UIKit
final class RedirectViewController: UIViewController {
func openRedirect(rawTarget: String) {
guard let target = URL(string: rawTarget) else { return }
UIApplication.shared.open(target)
}
}ตัวอย่างที่แก้ไขแล้ว
import SafariServices
import UIKit
final class RedirectViewController: UIViewController {
private let allowedHosts: Set<String> = ["app.example.com"]
func openRedirect(rawTarget: String) {
guard let target = URL(string: rawTarget),
target.scheme == "https",
let host = target.host,
allowedHosts.contains(host) else { return }
let browser = SFSafariViewController(url: target)
present(browser, animated: true)
}
}M7
Insufficient Binary Protections
Insufficient Binary Protections คือ binary ของแอปเปิดให้ถูกแกะ วิเคราะห์ ดัดแปลง หรือ repack ได้ง่ายจนกลไกป้องกันที่อยู่ฝั่ง client ถูกข้ามได้ เช่น ไม่มี tamper detection หรือไม่ตรวจว่าแอปทำงานบนเครื่องที่ถูกดัดแปลง การป้องกันนี้ไม่แทน server-side control แต่ช่วยเพิ่มต้นทุนและสัญญาณตรวจจับการโจมตี.
| สิ่งที่อาจผิดพลาด | แอปที่แจกจ่ายไม่ได้ต้านทานการแก้ไข การบรรจุใหม่ หรือการวิเคราะห์โดยไม่ได้รับอนุญาตเพียงพอตาม threat model |
|---|---|
| ผลกระทบต่อธุรกิจ | client ที่ถูกแก้ไขอาจเอาการควบคุมออก เปิดเผยรายละเอียดการทำงาน หรือปลอมเป็นแอปที่ผู้ใช้เชื่อถือ |
| จุดควบคุมแรกที่ควรตรวจ | เก็บการตัดสินใจด้านความเชื่อถือและ secret ไว้ฝั่งเซิร์ฟเวอร์ |
ผู้โจมตี เหยื่อ แอปพลิเคชัน จุดควบคุม

ภาพเปรียบเทียบเส้นทางที่ไม่ปลอดภัยกับจุดควบคุมที่ตัดเส้นทางนั้น กดภาพเพื่อดูขนาดเต็ม.
ผลกระทบที่ควรพิจารณา
client ที่ถูกแก้ไขอาจเอาการควบคุมออก เปิดเผยรายละเอียดการทำงาน หรือปลอมเป็นแอปที่ผู้ใช้เชื่อถือ
แนวทางลดความเสี่ยง
- เก็บการตัดสินใจด้านความเชื่อถือและ secret ไว้ฝั่งเซิร์ฟเวอร์
- ใช้การลงนามของแพลตฟอร์มและสัญญาณความสมบูรณ์ตามความเหมาะสม
- ตรวจจับการแก้ไขอย่างได้สัดส่วนและวางแผนการตอบสนองที่ปลอดภัย
ตัวอย่าง Android ด้วย Kotlin
ตัวอย่างที่มีช่องโหว่
import android.content.Intent
import android.net.Uri
import androidx.appcompat.app.AppCompatActivity
class RedirectActivity : AppCompatActivity() {
fun openRedirect(intent: Intent) {
val rawTarget = intent.data?.getQueryParameter("redirect") ?: return
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(rawTarget)))
}
}ตัวอย่างที่แก้ไขแล้ว
import android.content.Intent
import android.net.Uri
import androidx.browser.customtabs.CustomTabsIntent
import androidx.appcompat.app.AppCompatActivity
class RedirectActivity : AppCompatActivity() {
private val allowedHosts = setOf("app.example.com")
fun openRedirect(intent: Intent) {
val rawTarget = intent.data?.getQueryParameter("redirect") ?: return
val target = Uri.parse(rawTarget)
if (target.scheme != "https" || target.host !in allowedHosts) return
CustomTabsIntent.Builder().build().launchUrl(this, target)
}
}ตัวอย่าง iOS ด้วย Swift
ตัวอย่างที่มีช่องโหว่
import UIKit
final class RedirectViewController: UIViewController {
func openRedirect(rawTarget: String) {
guard let target = URL(string: rawTarget) else { return }
UIApplication.shared.open(target)
}
}ตัวอย่างที่แก้ไขแล้ว
import SafariServices
import UIKit
final class RedirectViewController: UIViewController {
private let allowedHosts: Set<String> = ["app.example.com"]
func openRedirect(rawTarget: String) {
guard let target = URL(string: rawTarget),
target.scheme == "https",
let host = target.host,
allowedHosts.contains(host) else { return }
let browser = SFSafariViewController(url: target)
present(browser, animated: true)
}
}M8
Security Misconfiguration
Security Misconfiguration บนมือถือคือการเปิดใช้ capability, component, debug setting, permission หรือ network policy เกินความจำเป็น เช่น exported activity ที่ไม่ควรเปิด, backup ที่นำข้อมูลออกได้ หรือ debug endpoint ที่ยังอยู่ใน release แอปอาจถูกเรียกจากแอปอื่นหรือเปิดข้อมูลในลักษณะที่หน้าจอปกติไม่เคยอนุญาต.
| สิ่งที่อาจผิดพลาด | build variant การตั้งค่าแพลตฟอร์ม component ที่เปิดเผย หรือการตั้งค่า backend ทำให้เกิดพฤติกรรมที่ไม่ตั้งใจ |
|---|---|
| ผลกระทบต่อธุรกิจ | ฟีเจอร์ debug component ที่เปิดเผย การสำรองข้อมูลที่เปิดกว้าง หรือการตั้งค่าการสื่อสารที่อ่อนแออาจเข้าถึงได้ใน release |
| จุดควบคุมแรกที่ควรตรวจ | ทบทวน manifest ของ release และการตั้งค่าแพลตฟอร์ม |
ผู้โจมตี เหยื่อ แอปพลิเคชัน จุดควบคุม

ภาพเปรียบเทียบเส้นทางที่ไม่ปลอดภัยกับจุดควบคุมที่ตัดเส้นทางนั้น กดภาพเพื่อดูขนาดเต็ม.
ผลกระทบที่ควรพิจารณา
ฟีเจอร์ debug component ที่เปิดเผย การสำรองข้อมูลที่เปิดกว้าง หรือการตั้งค่าการสื่อสารที่อ่อนแออาจเข้าถึงได้ใน release
แนวทางลดความเสี่ยง
- ทบทวน manifest ของ release และการตั้งค่าแพลตฟอร์ม
- แยกการตั้งค่า debug และ production
- ทำให้การตรวจการตั้งค่าเป็นอัตโนมัติใน CI
ตัวอย่าง Android ด้วย Kotlin
ตัวอย่างที่มีช่องโหว่
import android.content.Intent
import android.net.Uri
import androidx.appcompat.app.AppCompatActivity
class RedirectActivity : AppCompatActivity() {
fun openRedirect(intent: Intent) {
val rawTarget = intent.data?.getQueryParameter("redirect") ?: return
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(rawTarget)))
}
}ตัวอย่างที่แก้ไขแล้ว
import android.content.Intent
import android.net.Uri
import androidx.browser.customtabs.CustomTabsIntent
import androidx.appcompat.app.AppCompatActivity
class RedirectActivity : AppCompatActivity() {
private val allowedHosts = setOf("app.example.com")
fun openRedirect(intent: Intent) {
val rawTarget = intent.data?.getQueryParameter("redirect") ?: return
val target = Uri.parse(rawTarget)
if (target.scheme != "https" || target.host !in allowedHosts) return
CustomTabsIntent.Builder().build().launchUrl(this, target)
}
}ตัวอย่าง iOS ด้วย Swift
ตัวอย่างที่มีช่องโหว่
import UIKit
final class RedirectViewController: UIViewController {
func openRedirect(rawTarget: String) {
guard let target = URL(string: rawTarget) else { return }
UIApplication.shared.open(target)
}
}ตัวอย่างที่แก้ไขแล้ว
import SafariServices
import UIKit
final class RedirectViewController: UIViewController {
private let allowedHosts: Set<String> = ["app.example.com"]
func openRedirect(rawTarget: String) {
guard let target = URL(string: rawTarget),
target.scheme == "https",
let host = target.host,
allowedHosts.contains(host) else { return }
let browser = SFSafariViewController(url: target)
present(browser, animated: true)
}
}M9
Insecure Data Storage
Insecure Data Storage คือแอปบันทึกข้อมูลสำคัญไว้ในเครื่องโดยไม่มีการคุ้มครองที่เหมาะสม เช่น shared preferences, cache, log, screenshot, clipboard หรือไฟล์ backup ที่อ่านได้ ข้อมูลอาจหลุดผ่านเครื่องที่ root/jailbreak, backup, malware หรือผู้ที่เข้าถึงอุปกรณ์ชั่วคราว.
| สิ่งที่อาจผิดพลาด | ข้อมูลสำคัญถูกเก็บหรือ cache ไว้ในอุปกรณ์จนแอปอื่น ผู้ใช้เครื่อง ระบบสำรอง หรือกระบวนการตรวจพิสูจน์เข้าถึงได้ |
|---|---|
| ผลกระทบต่อธุรกิจ | อุปกรณ์สูญหาย root ใช้งานร่วมกัน หรือถูกสำรองข้อมูลอาจเปิดเผยข้อมูลบัญชี ธุรกิจ หรือส่วนบุคคล |
| จุดควบคุมแรกที่ควรตรวจ | ลดข้อมูลสำคัญที่เก็บในเครื่องและระยะเวลาของ cache |
ผู้โจมตี เหยื่อ แอปพลิเคชัน จุดควบคุม

ภาพเปรียบเทียบเส้นทางที่ไม่ปลอดภัยกับจุดควบคุมที่ตัดเส้นทางนั้น กดภาพเพื่อดูขนาดเต็ม.
ผลกระทบที่ควรพิจารณา
อุปกรณ์สูญหาย root ใช้งานร่วมกัน หรือถูกสำรองข้อมูลอาจเปิดเผยข้อมูลบัญชี ธุรกิจ หรือส่วนบุคคล
แนวทางลดความเสี่ยง
- ลดข้อมูลสำคัญที่เก็บในเครื่องและระยะเวลาของ cache
- ใช้ storage ที่แพลตฟอร์มปกป้องสำหรับ secret ที่จำเป็น
- ทบทวน log screenshot backup และพื้นที่เก็บข้อมูลร่วม
ตัวอย่าง Android ด้วย Kotlin
ตัวอย่างที่มีช่องโหว่
import android.content.Intent
import android.net.Uri
import androidx.appcompat.app.AppCompatActivity
class RedirectActivity : AppCompatActivity() {
fun openRedirect(intent: Intent) {
val rawTarget = intent.data?.getQueryParameter("redirect") ?: return
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(rawTarget)))
}
}ตัวอย่างที่แก้ไขแล้ว
import android.content.Intent
import android.net.Uri
import androidx.browser.customtabs.CustomTabsIntent
import androidx.appcompat.app.AppCompatActivity
class RedirectActivity : AppCompatActivity() {
private val allowedHosts = setOf("app.example.com")
fun openRedirect(intent: Intent) {
val rawTarget = intent.data?.getQueryParameter("redirect") ?: return
val target = Uri.parse(rawTarget)
if (target.scheme != "https" || target.host !in allowedHosts) return
CustomTabsIntent.Builder().build().launchUrl(this, target)
}
}ตัวอย่าง iOS ด้วย Swift
ตัวอย่างที่มีช่องโหว่
import UIKit
final class RedirectViewController: UIViewController {
func openRedirect(rawTarget: String) {
guard let target = URL(string: rawTarget) else { return }
UIApplication.shared.open(target)
}
}ตัวอย่างที่แก้ไขแล้ว
import SafariServices
import UIKit
final class RedirectViewController: UIViewController {
private let allowedHosts: Set<String> = ["app.example.com"]
func openRedirect(rawTarget: String) {
guard let target = URL(string: rawTarget),
target.scheme == "https",
let host = target.host,
allowedHosts.contains(host) else { return }
let browser = SFSafariViewController(url: target)
present(browser, animated: true)
}
}M10
Insufficient Cryptography
Insufficient Cryptography คือแอปเลือกหรือใช้อัลกอริทึม, key, random number หรือ library ผิดวิธี แม้จะมีคำว่า encryption อยู่ในระบบก็ตาม เช่น key เดาง่าย, ใช้โหมดเข้ารหัสไม่เหมาะสม หรือเก็บ key แบบอ่านได้ ผู้โจมตีที่ได้ข้อมูลหรือ key อาจถอดรหัสหรือปลอมข้อมูลได้.
| สิ่งที่อาจผิดพลาด | อัลกอริทึม mode ค่าสุ่ม กุญแจ หรือการใช้งานการเข้ารหัสไม่ปกป้องข้อมูลมือถือได้ตามที่ตั้งใจ |
|---|---|
| ผลกระทบต่อธุรกิจ | ข้อมูลที่ปกป้องด้วยการเข้ารหัสอ่อนแอหรือใช้งานผิดอาจถูกกู้คืนหรือแก้ไขได้ |
| จุดควบคุมแรกที่ควรตรวจ | ใช้ API การเข้ารหัสของแพลตฟอร์มและที่ผ่านการตรวจสอบ |
ผู้โจมตี เหยื่อ แอปพลิเคชัน จุดควบคุม

ภาพเปรียบเทียบเส้นทางที่ไม่ปลอดภัยกับจุดควบคุมที่ตัดเส้นทางนั้น กดภาพเพื่อดูขนาดเต็ม.
ผลกระทบที่ควรพิจารณา
ข้อมูลที่ปกป้องด้วยการเข้ารหัสอ่อนแอหรือใช้งานผิดอาจถูกกู้คืนหรือแก้ไขได้
แนวทางลดความเสี่ยง
- ใช้ API การเข้ารหัสของแพลตฟอร์มและที่ผ่านการตรวจสอบ
- สร้างและเก็บกุญแจด้วยการปกป้องของแพลตฟอร์ม
- หลีกเลี่ยงการเข้ารหัสที่พัฒนาเองและอัลกอริทึมล้าสมัย
ตัวอย่าง Android ด้วย Kotlin
ตัวอย่างที่มีช่องโหว่
import android.content.Intent
import android.net.Uri
import androidx.appcompat.app.AppCompatActivity
class RedirectActivity : AppCompatActivity() {
fun openRedirect(intent: Intent) {
val rawTarget = intent.data?.getQueryParameter("redirect") ?: return
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(rawTarget)))
}
}ตัวอย่างที่แก้ไขแล้ว
import android.content.Intent
import android.net.Uri
import androidx.browser.customtabs.CustomTabsIntent
import androidx.appcompat.app.AppCompatActivity
class RedirectActivity : AppCompatActivity() {
private val allowedHosts = setOf("app.example.com")
fun openRedirect(intent: Intent) {
val rawTarget = intent.data?.getQueryParameter("redirect") ?: return
val target = Uri.parse(rawTarget)
if (target.scheme != "https" || target.host !in allowedHosts) return
CustomTabsIntent.Builder().build().launchUrl(this, target)
}
}ตัวอย่าง iOS ด้วย Swift
ตัวอย่างที่มีช่องโหว่
import UIKit
final class RedirectViewController: UIViewController {
func openRedirect(rawTarget: String) {
guard let target = URL(string: rawTarget) else { return }
UIApplication.shared.open(target)
}
}ตัวอย่างที่แก้ไขแล้ว
import SafariServices
import UIKit
final class RedirectViewController: UIViewController {
private let allowedHosts: Set<String> = ["app.example.com"]
func openRedirect(rawTarget: String) {
guard let target = URL(string: rawTarget),
target.scheme == "https",
let host = target.host,
allowedHosts.contains(host) else { return }
let browser = SFSafariViewController(url: target)
present(browser, animated: true)
}
}
