Code Injection là một loại tấn công trong đó kẻ tấn công truyền mã độc qua dữ liệu đầu vào của ứng dụng để thực hiện các thao tác trái phép. Theo OWASP, 2024, chèn mã nằm trong top ba lỗ hổng nghiêm trọng nhất. Hiểu được cơ chế của chèn mã cho phép các nhà phát triển thiết kế hệ thống an toàn ngay từ ngày đầu phát triển.
Những điểm chính
Code Injection là một lớp tấn công trong đó kẻ tấn công chèn mã thực thi vào ứng dụng thông qua dữ liệu đầu vào không đáng tin cậy. Trong ứng dụng di động, cuộc tấn công có thể xảy ra qua các trường nhập liệu, deep link, thông báo push, mã QR và trao đổi tệp.
Không giống như các cuộc tấn công cấp hệ điều hành, Code Injection khai thác lỗi logic trong mã của chính ứng dụng: thiếu thoát ký tự, nối chuỗi không an toàn hoặc tin tưởng vào nguồn dữ liệu bên ngoài. Theo báo cáo của Positive Technologies (2025), chèn mã chiếm 23% tất cả các lỗ hổng trong ứng dụng di động trong lĩnh vực tài chính.
Nguy cơ chính của Code Injection là sự xâm phạm dữ liệu hoàn toàn: kẻ tấn công có thể truy cập vào cơ sở dữ liệu, hệ thống tệp của thiết bị hoặc tài khoản của người dùng khác. Đối với ứng dụng di động xử lý dữ liệu thanh toán hoặc thông tin y tế, hậu quả có thể rất nghiêm trọng.
Các nhà phát triển cần hiểu các loại chèn mã và áp dụng cơ chế bảo vệ ở tất cả các cấp độ — từ nhập dữ liệu đến hiển thị và lưu trữ. Các framework hiện đại cung cấp công cụ bảo mật tích hợp, nhưng việc sử dụng chúng đòi hỏi một cách tiếp cận có ý thức.
Phân loại Code Injection bao gồm ba loại tấn công chính trong bối cảnh phát triển di động. Mỗi loại khai thác các thành phần khác nhau của ứng dụng và yêu cầu các phương pháp bảo vệ cụ thể.
SQL Injection (SQLi) là chèn mã SQL độc hại qua các tham số truy vấn đến cơ sở dữ liệu cục bộ hoặc từ xa. Trong ứng dụng di động, lỗ hổng phát sinh khi làm việc không an toàn với SQLite trên thiết bị hoặc khi xây dựng yêu cầu HTTP đến REST API với nối chuỗi.
Một vector tấn công điển hình là trường tìm kiếm hoặc bộ lọc có giá trị được thay thế trực tiếp vào truy vấn SQL. Nếu nhà phát triển sử dụng nối chuỗi trực tiếp thay vì truy vấn tham số hóa, kẻ tấn công có thể truyền một chuỗi như 1' OR '1'='1. Theo OWASP Mobile Top 10 (2024), SQL Injection vẫn là lỗ hổng nghiêm trọng phổ biến thứ hai trong ứng dụng di động trong danh mục lưu trữ dữ liệu không an toàn.
Bảo vệ chống SQLi được xây dựng trên ba cấp độ: sử dụng truy vấn tham số hóa (PreparedStatement trong Java, rawQuery với bindArgs trong Android), xác thực đầu vào phía máy khách và máy chủ, và quyền tối thiểu của cơ sở dữ liệu.
Các cuộc tấn công XSS trong ứng dụng di động nhắm vào thành phần WebView — một trình duyệt tích hợp hiển thị nội dung HTML. Nếu ứng dụng tải dữ liệu từ nguồn bên ngoài vào WebView mà không làm sạch, kẻ tấn công có thể chèn mã JavaScript thực thi trong ngữ cảnh của ứng dụng.
Có hai loại phụ của XSS: XSS Lưu trữ — tập lệnh độc hại được lưu trên máy chủ và thực thi mỗi khi trang được xem, và XSS Phản chiếu — mã được truyền qua URL hoặc tham số POST và thực thi một lần. Trong ứng dụng di động, XSS Lưu trữ qua bình luận, đánh giá hoặc nội dung người dùng hiển thị trong WebView cho người dùng khác đặc biệt nguy hiểm.
Bảo vệ bao gồm vô hiệu hóa JavaScript trong WebView nếu không cần thiết, sử dụng Content Security Policy (CSP) và làm sạch nội dung HTML qua các thư viện như Jsoup cho Android hoặc SwiftSoup cho iOS.
Command Injection là thực thi các lệnh hệ thống trên thiết bị qua các lời gọi không được làm sạch đến Runtime.exec(), ProcessBuilder hoặc NSTask. Trong ứng dụng di động, cuộc tấn công có thể xảy ra nếu ứng dụng truyền dữ liệu người dùng vào các lệnh shell hoặc Intent có hành động.
Các khu vực dễ bị tấn công nhất là chức năng chuyển đổi tệp, xử lý đa phương tiện (ffmpeg, ImageMagick) và cài đặt thư viện bên thứ ba. Kẻ tấn công có thể truyền một lệnh với ký tự pipe hoặc chuyển hướng thực thi mã tùy ý trên thiết bị. Android hạn chế một phần quyền truy cập shell qua sandbox, nhưng ứng dụng có quyền root hoặc khai thác PrivEsc có thể bị xâm phạm.
Biện pháp bảo vệ được khuyến nghị là từ chối hoàn toàn Runtime.exec() để xử lý dữ liệu người dùng, sử dụng thư viện với API an toàn và cô lập nghiêm ngặt các quy trình bên ngoài.
Cơ chế của Code Injection khác nhau trên nền tảng Android và iOS do sự khác biệt về kiến trúc. Trên Android, chèn mã thường liên quan đến Intent — một thông báo hệ thống được truyền giữa các thành phần của ứng dụng. Kẻ tấn công có thể gửi một Intent độc hại với dữ liệu bổ sung chứa mã SQL hoặc lệnh shell.
Trên iOS, các cuộc tấn công thường xảy ra qua cơ chế Giao tiếp liên tiến trình (XPC), Universal Links và xử lý URL Scheme. Một ứng dụng chấp nhận dữ liệu từ nguồn bên ngoài mà không xác thực sẽ trở nên dễ bị chèn mã. Theo Apple Security Research (2025), khoảng 12% lỗ hổng trong ứng dụng iOS liên quan đến việc làm sạch dữ liệu đầu vào không đầy đủ.
Một vector chung cho cả hai nền tảng là tấn công qua bộ nhớ cục bộ (SQLite, Realm, UserDefaults). Nếu một ứng dụng độc hại có thể ghi dữ liệu vào thư mục dùng chung, nó có thể chèn mã sẽ được thực thi bởi ứng dụng mục tiêu khi đọc.
Quy trình tấn công điển hình bao gồm ba giai đoạn: trinh sát — phân tích các điểm đầu vào của ứng dụng (biểu mẫu, deep link, tệp), chèn — phân phối tải trọng độc hại qua điểm đầu vào đã tìm thấy, và khai thác — thực thi chèn mã để truy cập dữ liệu hoặc chức năng. Hiểu chu trình này giúp nhà phát triển thiết kế bảo vệ ở mỗi giai đoạn.
Hãy xem các ví dụ cụ thể về Code Injection trong Kotlin cho Android và Swift cho iOS. Mỗi ví dụ cho thấy một mẫu dễ bị tấn công và giải pháp thay thế an toàn của nó.
Ví dụ đầu tiên là nối trực tiếp chuỗi truy vấn với đầu vào của người dùng. Với giá trị userInput = "1' OR '1'='1", truy vấn trả về tất cả các hàng của bảng thay vì một hàng.
// DỄ BỊ TẤN CÔNG: nối chuỗi
fun getUserById(userInput: String): List<User> {
val db = openOrCreateDatabase()
val query = "SELECT * FROM users WHERE id = " + userInput
return db.rawQuery(query, null)
}
// AN TOÀN: truy vấn tham số hóa
fun getUserByIdSafe(userInput: String): List<User> {
val db = openOrCreateDatabase()
val query = "SELECT * FROM users WHERE id = ?"
return db.rawQuery(query, arrayOf(userInput))
}
Ví dụ thứ hai minh họa việc tải nội dung HTML người dùng không đúng cách và đúng cách trong WKWebView. Sử dụng SwiftSoup cho phép loại bỏ các tập lệnh độc hại trước khi hiển thị.
// DỄ BỊ TẤN CÔNG: tải HTML trực tiếp
let webView = WKWebView()
let html = "<div>\(userComment)</div>"
webView.loadHTMLString(html, baseURL: nil)
// AN TOÀN: làm sạch qua SwiftSoup
import SwiftSoup
let cleanHtml = try SwiftSoup.clean(
userComment,
Whitelist.basic()
)
webView.loadHTMLString(cleanHtml, baseURL: nil)
Ví dụ thứ ba là sự nguy hiểm của việc gọi Runtime.exec() với đối số người dùng và giải pháp thay thế an toàn qua thư viện với API cố định.
// DỄ BỊ TẤN CÔNG: lệnh shell với đầu vào người dùng
fun convertVideo(inputPath: String) {
val cmd = "ffmpeg -i $inputPath -vcodec libx264 output.mp4"
Runtime.getRuntime().exec(cmd)
}
// AN TOÀN: cô lập đối số
fun convertVideoSafe(inputPath: String) {
val cmd = listOf(
"ffmpeg", "-i", inputPath,
"-vcodec", "libx264", "output.mp4"
)
ProcessBuilder(cmd).start()
}
Bảo vệ khỏi Code Injection đòi hỏi một cách tiếp cận có hệ thống bao gồm mã, cơ sở hạ tầng và quy trình phát triển. Không có phương pháp đơn lẻ nào đảm bảo an toàn tuyệt đối — cần có sự kết hợp các biện pháp.
Cấp độ đầu tiên là phòng ngừa: xác thực nghiêm ngặt tất cả dữ liệu đầu vào. Mọi trường mà ứng dụng nhận từ người dùng, ứng dụng khác hoặc mạng phải được kiểm tra về loại, độ dài và định dạng. Các thư viện như OWASP ESAPI cung cấp trình xác thực có sẵn cho các tình huống phổ biến.
Cấp độ thứ hai là làm sạch và thoát ký tự: chuyển đổi dữ liệu trước khi sử dụng trong truy vấn SQL, mẫu HTML hoặc lệnh shell. Truy vấn tham số hóa loại bỏ hoàn toàn SQL Injection và thoát HTML ngăn chặn XSS. Trên Android, hãy sử dụng Room để làm việc với SQLite — một ORM tự động áp dụng các tham số bind.
Cấp độ thứ ba là giảm thiểu đặc quyền: ứng dụng nên hoạt động với quyền tối thiểu cần thiết. Sử dụng nguyên tắc đặc quyền tối thiểu cho cơ sở dữ liệu, hệ thống tệp và giao tiếp liên tiến trình. iOS thực hiện nguyên tắc này qua sandbox ứng dụng và Android qua mô hình quyền và cô lập tiến trình.
Cấp độ thứ tư là giám sát và phản ứng: ghi nhật ký các hoạt động đáng ngờ, phát hiện bất thường và tự động chặn khi các cuộc tấn công lặp lại. Các công cụ như Firebase App Check giúp phát hiện các yêu cầu giả mạo đến backend từ các máy khách bị xâm phạm. Tích hợp RASP (Runtime Application Self-Protection) cho phép chặn chèn mã trong thời gian chạy.
Theo nghiên cứu của Google Project Zero (2025), sự kết hợp của bốn cấp độ này giảm nguy cơ tấn công Code Injection thành công xuống 94%. Các nhà phát triển được khuyến nghị triển khai cơ chế bảo vệ ở giai đoạn thiết kế kiến trúc, thay vì thêm chúng sau khi phát hiện lỗ hổng.
Câu hỏi thường gặp
Code Injection là khi kẻ tấn công gửi cho ứng dụng không phải dữ liệu mà là mã. Ví dụ, thay vì tên người dùng, họ gửi một truy vấn SQL mà ứng dụng thực thi trong cơ sở dữ liệu của nó, truy cập vào các bản ghi của người khác.
SQL Injection tấn công cơ sở dữ liệu qua các truy vấn SQL, cho phép đọc và sửa đổi bản ghi. XSS chèn mã JavaScript vào WebView để thực thi trong trình duyệt của người dùng. Mục tiêu khác nhau, nhưng cơ chế chung — xác thực đầu vào không đầy đủ.
Sử dụng Room với truy vấn tham số hóa cho SQLite, vô hiệu hóa JavaScript trong WebView, áp dụng ProGuard/R8 để làm rối mã và không bao giờ truyền dữ liệu người dùng vào Runtime.exec(). Thường xuyên cập nhật các phụ thuộc với bản vá bảo mật.
Có, ứng dụng iOS dễ bị SQL Injection qua Core Data (truy vấn thô), XSS qua WKWebView và Command Injection qua Process. Sandbox iOS giới hạn quy mô của cuộc tấn công nhưng không ngăn chặn hoàn toàn. Luôn làm sạch dữ liệu trước khi sử dụng.
Sử dụng SAST (Static Analysis) — các công cụ như SonarQube, MobSF hoặc QARK để quét mã nguồn. Ngoài ra, sử dụng máy quét DAST để kiểm tra ứng dụng đang chạy: nhập các chuỗi được tạo đặc biệt (‘, OR 1=1, <script>) vào tất cả các trường nhập liệu.
Tóm tắt
Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay
IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.
Đọc thêm