Code Injection เป็นประเภทการโจมตีที่ผู้โจมตีส่งโค้ดที่เป็นอันตรายผ่านข้อมูลนำเข้าของแอปพลิเคชันเพื่อดำเนินการที่ไม่ได้รับอนุญาต ตามข้อมูลของ OWASP, 2024 การฉีดโค้ดเป็นหนึ่งในสามช่องโหว่ที่ร้ายแรงที่สุด การทำความเข้าใจกลไกของ การฉีดโค้ด ช่วยให้นักพัฒนาสามารถออกแบบระบบที่ปลอดภัยตั้งแต่วันแรกของการพัฒนา
ประเด็นสำคัญ
Code Injection คือประเภทของการโจมตีที่ผู้โจมตีฉีดโค้ดที่สามารถดำเนินการได้ลงในแอปพลิเคชันผ่านข้อมูลนำเข้าที่ไม่น่าเชื่อถือ ในแอปพลิเคชันมือถือ การโจมตีสามารถเกิดขึ้นได้ผ่านฟิลด์อินพุต ลิงก์ลึก การแจ้งเตือนแบบพุช รหัส QR และการแลกเปลี่ยนไฟล์
แตกต่างจากการโจมตีระดับระบบปฏิบัติการ Code Injection ใช้ประโยชน์จากข้อผิดพลาดเชิงตรรกะในโค้ดของแอปพลิเคชันเอง: การขาดการหลบหนี การต่อสตริงที่ไม่ปลอดภัย หรือความไว้วางใจในแหล่งข้อมูลภายนอก ตามรายงานของ Positive Technologies (2025) การฉีดโค้ด คิดเป็น 23% ของช่องโหว่ทั้งหมดในแอปพลิเคชันมือถือในภาคการเงิน
อันตรายหลักของ Code Injection คือการประนีประนอมข้อมูลโดยสมบูรณ์: ผู้โจมตีสามารถเข้าถึงฐานข้อมูล ระบบไฟล์ของอุปกรณ์ หรือบัญชีของผู้ใช้รายอื่น สำหรับแอปพลิเคชันมือถือที่จัดการกับข้อมูลการชำระเงินหรือข้อมูลทางการแพทย์ ผลที่ตามมาอาจร้ายแรง
นักพัฒนาต้องเข้าใจประเภทของการฉีดโค้ดและใช้กลไกการป้องกันในทุกระดับ ตั้งแต่การป้อนข้อมูลไปจนถึงการแสดงผลและการจัดเก็บ เฟรมเวิร์กสมัยใหม่มีเครื่องมือรักษาความปลอดภัยในตัว แต่การใช้งานต้องใช้แนวทางที่มีสติ
การจำแนกประเภท Code Injection ประกอบด้วยการโจมตีหลักสามประเภทในบริบทของการพัฒนามือถือ แต่ละประเภทใช้ประโยชน์จากส่วนประกอบต่าง ๆ ของแอปพลิเคชันและต้องการวิธีการป้องกันเฉพาะ
SQL Injection (SQLi) คือการฉีดโค้ด SQL ที่เป็นอันตรายผ่านพารามิเตอร์คำสั่งสอบถามไปยังฐานข้อมูลในเครื่องหรือระยะไกล ในแอปพลิเคชันมือถือ ช่องโหว่เกิดขึ้นเมื่อทำงานกับ SQLite บนอุปกรณ์อย่างไม่ปลอดภัยหรือเมื่อสร้างคำขอ HTTP ไปยัง REST API ด้วยการต่อสตริง
เวกเตอร์การโจมตีทั่วไปคือฟิลด์ค้นหาหรือกรองซึ่งค่าถูกแทนที่โดยตรงในคำสั่ง SQL หากนักพัฒนาใช้การต่อโดยตรงแทนคำสั่งสอบถามแบบกำหนดพารามิเตอร์ ผู้โจมตีสามารถส่งสตริงเช่น 1' OR '1'='1 ตาม OWASP Mobile Top 10 (2024) SQL Injection ยังคงเป็นช่องโหว่ร้ายแรงที่พบบ่อยเป็นอันดับสองในแอปพลิเคชันมือถือในหมวดหมู่การจัดเก็บข้อมูลที่ไม่ปลอดภัย
การป้องกัน SQLi สร้างขึ้นจากสามระดับ: การใช้คำสั่งสอบถามแบบกำหนดพารามิเตอร์ (PreparedStatement ใน Java, rawQuery พร้อม bindArgs ใน Android) การตรวจสอบอินพุตทั้งฝั่งไคลเอ็นต์และเซิร์ฟเวอร์ และสิทธิ์ฐานข้อมูลขั้นต่ำ
การโจมตี XSS ในแอปพลิเคชันมือถือกำหนดเป้าหมายไปที่ส่วนประกอบ WebView ซึ่งเป็นเบราว์เซอร์ในตัวที่แสดงเนื้อหา HTML หากแอปพลิเคชันโหลดข้อมูลจากแหล่งภายนอกเข้าสู่ WebView โดยไม่ทำความสะอาด ผู้โจมตีสามารถฉีด โค้ด JavaScript ที่ดำเนินการในบริบทของแอปพลิเคชัน
มีสองประเภทย่อยของ XSS: Stored XSS — สคริปต์อันตรายถูกบันทึกบนเซิร์ฟเวอร์และดำเนินการทุกครั้งที่ดูหน้า และ Reflected XSS — โค้ดถูกส่งผ่าน URL หรือพารามิเตอร์ POST และดำเนินการครั้งเดียว ในแอปพลิเคชันมือถือ Stored XSS ผ่านความคิดเห็น รีวิว หรือเนื้อหาผู้ใช้ที่แสดงใน WebView ให้ผู้ใช้รายอื่นเป็นอันตรายอย่างยิ่ง
การป้องกันรวมถึงการปิดการใช้งาน JavaScript ใน WebView หากไม่จำเป็น การใช้ Content Security Policy (CSP) และการทำความสะอาดเนื้อหา HTML ผ่านไลบรารีเช่น Jsoup สำหรับ Android หรือ SwiftSoup สำหรับ iOS
Command Injection คือการดำเนินการคำสั่งระบบบนอุปกรณ์ผ่านการเรียก Runtime.exec(), ProcessBuilder หรือ NSTask ที่ไม่ได้รับการทำความสะอาด ในแอปพลิเคชันมือถือ การโจมตีเป็นไปได้หากแอปพลิเคชันส่งข้อมูลผู้ใช้ไปยังคำสั่ง shell หรือ Intent ที่มีการดำเนินการ
พื้นที่ที่เสี่ยงที่สุดคือฟังก์ชันการแปลงไฟล์ การประมวลผลสื่อ (ffmpeg, ImageMagick) และการติดตั้งไลบรารีของบุคคลที่สาม ผู้โจมตีสามารถส่งคำสั่งที่มีอักขระไปป์หรือการเปลี่ยนเส้นทางซึ่งดำเนินการโค้ดตามอำเภอใจบนอุปกรณ์ Android จำกัดการเข้าถึง shell บางส่วนผ่านแซนด์บ็อกซ์ แต่แอปพลิเคชันที่มีสิทธิ์รูทหรือการโจมตี PrivEsc อาจถูกประนีประนอม
การป้องกันที่แนะนำคือการปฏิเสธ Runtime.exec() โดยสมบูรณ์สำหรับการประมวลผลข้อมูลผู้ใช้ การใช้ไลบรารีที่มี API ที่ปลอดภัย และการแยกกระบวนการภายนอกอย่างเข้มงวด
กลไกของ Code Injection แตกต่างกันบนแพลตฟอร์ม Android และ iOS เนื่องจากความแตกต่างทางสถาปัตยกรรม บน Android การฉีดโค้ดมักเกี่ยวข้องกับ Intent ซึ่งเป็นข้อความระบบที่ส่งระหว่างส่วนประกอบของแอปพลิเคชัน ผู้โจมตีสามารถส่ง Intent ที่เป็นอันตรายพร้อมข้อมูลเพิ่มเติมที่มีโค้ด SQL หรือคำสั่ง shell
บน iOS การโจมตีมักเกิดขึ้นผ่านกลไกการสื่อสารระหว่างกระบวนการ (XPC), Universal Links และการจัดการ URL Scheme แอปพลิเคชันที่รับข้อมูลจากแหล่งภายนอกโดยไม่ตรวจสอบจะกลายเป็นเสี่ยงต่อการฉีดโค้ด ตาม Apple Security Research (2025) ประมาณ 12% ของช่องโหว่ในแอปพลิเคชัน iOS เกี่ยวข้องกับการทำความสะอาดข้อมูลนำเข้าที่ไม่เพียงพอ
เวกเตอร์ทั่วไปสำหรับทั้งสองแพลตฟอร์มคือการโจมตีผ่านพื้นที่จัดเก็บในเครื่อง (SQLite, Realm, UserDefaults) หากแอปพลิเคชันที่เป็นอันตรายสามารถเขียนข้อมูลไปยังไดเรกทอรีที่ใช้ร่วมกันได้ มันสามารถฉีดโค้ดที่จะถูกดำเนินการโดยแอปพลิเคชันเป้าหมายเมื่ออ่าน
กระบวนการโจมตีทั่วไปประกอบด้วยสามขั้นตอน: การสอดแนม — การวิเคราะห์จุดนำเข้าของแอปพลิเคชัน (ฟอร์ม ลิงก์ลึก ไฟล์) การฉีด — การส่งเพย์โหลดที่เป็นอันตรายผ่านจุดนำเข้าที่พบ และการใช้ประโยชน์ — การดำเนินการฉีดโค้ดเพื่อเข้าถึงข้อมูลหรือฟังก์ชันการทำงาน การทำความเข้าใจวงจรนี้ช่วยให้นักพัฒนาออกแบบการป้องกันในแต่ละขั้นตอน
มาดูตัวอย่างเฉพาะของ Code Injection ใน Kotlin สำหรับ Android และ Swift สำหรับ iOS แต่ละตัวอย่างแสดงรูปแบบที่ไม่ปลอดภัยและทางเลือกที่ปลอดภัย
ตัวอย่างแรกคือการต่อสตริงคำสั่งสอบถามโดยตรงกับอินพุตของผู้ใช้ ด้วยค่า userInput = "1' OR '1'='1" คำสั่งสอบถามจะส่งคืนทุกแถวของตารางแทนที่จะเป็นหนึ่งแถว
// ไม่ปลอดภัย: การต่อสตริง
fun getUserById(userInput: String): List<User> {
val db = openOrCreateDatabase()
val query = "SELECT * FROM users WHERE id = " + userInput
return db.rawQuery(query, null)
}
// ปลอดภัย: คำสั่งสอบถามแบบกำหนดพารามิเตอร์
fun getUserByIdSafe(userInput: String): List<User> {
val db = openOrCreateDatabase()
val query = "SELECT * FROM users WHERE id = ?"
return db.rawQuery(query, arrayOf(userInput))
}
ตัวอย่างที่สองสาธิตการโหลดเนื้อหา HTML ของผู้ใช้ที่ไม่ถูกต้องและถูกต้องใน WKWebView การใช้ SwiftSoup ช่วยให้ลบสคริปต์อันตรายก่อนการแสดงผล
// ไม่ปลอดภัย: การโหลด HTML โดยตรง
let webView = WKWebView()
let html = "<div>\(userComment)</div>"
webView.loadHTMLString(html, baseURL: nil)
// ปลอดภัย: การทำความสะอาดผ่าน SwiftSoup
import SwiftSoup
let cleanHtml = try SwiftSoup.clean(
userComment,
Whitelist.basic()
)
webView.loadHTMLString(cleanHtml, baseURL: nil)
ตัวอย่างที่สามคืออันตรายของการเรียก Runtime.exec() ด้วยอาร์กิวเมนต์ของผู้ใช้และทางเลือกที่ปลอดภัยผ่านไลบรารีที่มี API คงที่
// ไม่ปลอดภัย: คำสั่ง shell พร้อมอินพุตผู้ใช้
fun convertVideo(inputPath: String) {
val cmd = "ffmpeg -i $inputPath -vcodec libx264 output.mp4"
Runtime.getRuntime().exec(cmd)
}
// ปลอดภัย: การแยกอาร์กิวเมนต์
fun convertVideoSafe(inputPath: String) {
val cmd = listOf(
"ffmpeg", "-i", inputPath,
"-vcodec", "libx264", "output.mp4"
)
ProcessBuilder(cmd).start()
}
การป้องกัน Code Injection ต้องใช้แนวทางที่เป็นระบบครอบคลุมโค้ด โครงสร้างพื้นฐาน และกระบวนการพัฒนา ไม่มีวิธีการเดียวที่รับประกันความปลอดภัยอย่างสมบูรณ์ — จำเป็นต้องมีการผสมผสานของแนวปฏิบัติ
ระดับแรกคือการป้องกัน: การตรวจสอบข้อมูลนำเข้าทั้งหมดอย่างเข้มงวด ทุกฟิลด์ที่แอปพลิเคชันได้รับจากผู้ใช้ แอปพลิเคชันอื่น หรือเครือข่ายต้องถูกตรวจสอบประเภท ความยาว และรูปแบบ ไลบรารีเช่น OWASP ESAPI มีตัวตรวจสอบความถูกต้องพร้อมใช้สำหรับสถานการณ์ทั่วไป
ระดับที่สองคือการทำความสะอาดและการหลบหนี: การแปลงข้อมูลก่อนใช้ในคำสั่ง SQL เทมเพลต HTML หรือคำสั่ง shell คำสั่งสอบถามแบบกำหนดพารามิเตอร์กำจัด SQL Injection โดยสมบูรณ์ และการหลบหนี HTML ป้องกัน XSS บน Android ใช้ Room สำหรับการทำงานกับ SQLite ซึ่งเป็น ORM ที่ใช้พารามิเตอร์ bind โดยอัตโนมัติ
ระดับที่สามคือการลดสิทธิ์: แอปพลิเคชันควรทำงานด้วยสิทธิ์ขั้นต่ำที่จำเป็น ใช้หลักการสิทธิ์น้อยที่สุดสำหรับฐานข้อมูล ระบบไฟล์ และการสื่อสารระหว่างกระบวนการ iOS ใช้หลักการนี้ผ่านแซนด์บ็อกซ์ของแอปพลิเคชัน และ Android ผ่านโมเดลสิทธิ์และการแยกกระบวนการ
ระดับที่สี่คือการตรวจสอบและตอบสนอง: การบันทึกการดำเนินการที่น่าสงสัย การตรวจจับความผิดปกติ และการบล็อกอัตโนมัติเมื่อมีการโจมตีซ้ำ เครื่องมือเช่น Firebase App Check ช่วยตรวจจับคำขอปลอมไปยังแบ็กเอนด์จากไคลเอ็นต์ที่ถูกประนีประนอม การรวม RASP (Runtime Application Self-Protection) ช่วยให้สามารถบล็อกการฉีดโค้ดในรันไทม์
จากการศึกษาของ Google Project Zero (2025) การรวมสี่ระดับนี้ช่วยลดความเสี่ยงของการโจมตี Code Injection ที่สำเร็จได้ 94% นักพัฒนาแนะนำให้ใช้กลไกการป้องกันในขั้นตอนการออกแบบสถาปัตยกรรม แทนที่จะเพิ่มหลังจากค้นพบช่องโหว่
คำถามที่พบบ่อย
Code Injection คือเมื่อผู้โจมตีส่งไม่ใช่ข้อมูล แต่เป็นโค้ดไปยังแอปพลิเคชัน ตัวอย่างเช่น แทนที่จะเป็นชื่อผู้ใช้ พวกเขาส่งคำสั่ง SQL ที่แอปพลิเคชันดำเนินการในฐานข้อมูลของตน เข้าถึงบันทึกของผู้ใช้รายอื่น
SQL Injection โจมตีฐานข้อมูลผ่านคำสั่ง SQL ทำให้สามารถอ่านและแก้ไขบันทึกได้ XSS ฉีดโค้ด JavaScript ลงใน WebView เพื่อดำเนินการในเบราว์เซอร์ของผู้ใช้ เป้าหมายต่างกัน แต่กลไกเดียวกัน — การตรวจสอบอินพุตที่ไม่เพียงพอ
ใช้ Room พร้อมคำสั่งสอบถามแบบกำหนดพารามิเตอร์สำหรับ SQLite ปิดการใช้งาน JavaScript ใน WebView ใช้ ProGuard/R8 สำหรับการทำให้โค้ดสับสน และอย่าส่งข้อมูลผู้ใช้ไปยัง Runtime.exec() อัปเดต dependencies ด้วยแพตช์ความปลอดภัยเป็นประจำ
ใช่ แอปพลิเคชัน iOS เสี่ยงต่อ SQL Injection ผ่าน Core Data (คำสั่งดิบ) XSS ผ่าน WKWebView และ Command Injection ผ่าน Process แซนด์บ็อกซ์ iOS จำกัดขอบเขตของการโจมตีแต่ไม่ได้ป้องกันอย่างสมบูรณ์ ทำความสะอาดข้อมูลก่อนใช้งานเสมอ
ใช้ SAST (Static Analysis) — เครื่องมือเช่น SonarQube, MobSF หรือ QARK สำหรับสแกนซอร์สโค้ด นอกจากนี้ ใช้เครื่องสแกน DAST สำหรับทดสอบแอปพลิเคชันที่ทำงานอยู่: ป้อนสตริงที่สร้างขึ้นเป็นพิเศษ (‘, OR 1=1, <script>) ในทุกฟิลด์อินพุต
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ
อ่านเพิ่มเติม