SQL Injection dalam pengembangan mobile: apa itu, metode serangan dan perlindungan

Penulis: IT Sectr Diterbitkan: 2026-04-06 Waktu membaca: 9 mnt

SQL Injection — jenis serangan pada database aplikasi di mana penyerang menyuntikkan kode SQL berbahaya ke dalam parameter permintaan, mendapatkan akses tidak sah ke data atau kemampuan untuk memodifikasinya. Menurut data OWASP (2025), SQL Injection tetap menjadi salah satu kerentanan kritis yang dapat menyebabkan kompromi total pada database. Injeksi kode SQL memungkinkan penyerang membaca, mengubah, dan menghapus catatan, dan dalam beberapa kasus — mendapatkan akses ke sistem operasi server.

Poin utama

  • SQL Injection — penyuntikan kode SQL melalui parameter pengguna yang mengubah logika permintaan ke database
  • Parameterisasi permintaan — metode perlindungan utama: memisahkan kode SQL dari data menggunakan prepared statements
  • Jenis serangan — injeksi klasik (melalui WHERE), Blind SQLi (kesimpulan logis), UNION-based (membaca tabel lain)
  • Error-based SQLi — ekstraksi data melalui pesan kesalahan database
  • Framework ORM — mengurangi risiko SQLi jika digunakan dengan benar, tetapi tidak menghilangkannya sepenuhnya

Apa itu SQL Injection?

SQL Injection adalah kerentanan yang muncul ketika aplikasi membentuk permintaan SQL melalui penggabungan string dengan data pengguna. Penyerang mengirimkan string yang dibuat khusus ke parameter permintaan yang mengubah struktur perintah SQL. Alih-alih menjadi data, string yang dimasukkan menjadi bagian dari kode SQL, memungkinkan penyerang untuk menjalankan permintaan sewenang-wenang ke database. Menurut Verizon Data Breach Report (2025), SQL Injection hadir dalam 8% dari semua kebocoran data yang diteliti.

Mengapa SQL Injection masih relevan?

Meskipun kerentanan ini sudah dikenal (pertama disebutkan — akhir 1990-an), SQL Injection masih ditemukan di aplikasi modern. Penyebabnya — faktor manusia: pengembang membiarkan penggabungan string dalam kode, kode legacy tidak direfaktor, dan framework ORM digunakan secara tidak benar (misalnya, permintaan mentah dengan substitusi nilai melalui string). Menurut data Veracode (2026), sekitar 14% dari semua aplikasi yang dipindai mengandung setidaknya satu kerentanan SQLi.

Apa yang bisa dilakukan penyerang?

SQL Injection yang berhasil memberikan penyerang berbagai kemampuan: membaca tabel database apa pun, termasuk hash kata sandi dan data pribadi pengguna; memodifikasi dan menghapus catatan; menjalankan operasi administratif (DROP TABLE, TRUNCATE); dalam beberapa konfigurasi — eksekusi perintah jarak jauh melalui xp_cmdshell (MSSQL) atau INTO OUTFILE (MySQL). Konsekuensinya — mulai dari kebocoran data pengguna hingga hilangnya kendali penuh atas sistem.

Jenis injeksi SQL

Injeksi SQL diklasifikasikan berdasarkan cara ekstraksi data dari database. Pemilihan metode tergantung pada bagaimana aplikasi memproses hasil permintaan dan pesan kesalahan. Klasifikasi OWASP membedakan tiga jenis utama: In-band (data diekstrak melalui saluran yang sama), Inferential/Blind (kesimpulan logis) dan Out-of-band (data dikirim melalui saluran lain).

JenisCara ekstraksi dataKompleksitasFrekuensi
In-band (klasik)Langsung melalui hasil permintaanRendahTinggi
Blind SQLiKesimpulan logis berdasarkan respons serverTinggiSedang
Out-of-bandMelalui saluran eksternal (DNS, HTTP)SedangRendah

In-band SQL Injection (klasik)

Jenis yang paling umum. Penyerang menyuntikkan kode SQL ke parameter permintaan, dan hasil injeksi terlihat langsung dalam respons server. Dua subtipe: Error-based (melalui pesan kesalahan database) dan UNION-based (melalui operator UNION SELECT). Error-based menggunakan informasi dari pesan kesalahan, misalnya kesalahan sintaks MySQL yang dapat mengungkapkan nama tabel atau struktur permintaan. UNION-based memungkinkan menggabungkan hasil permintaan yang sah dengan data dari tabel database lain.

Blind SQL Injection (buta)

Digunakan ketika aplikasi tidak menampilkan hasil permintaan atau pesan kesalahan. Penyerang mengajukan pertanyaan „ya/tidak” dengan mengirimkan permintaan dengan kondisi logis dan menganalisis perbedaan dalam respons server (misalnya, waktu respons atau konten halaman). Time-based Blind SQLi menggunakan fungsi penundaan (SLEEP, WAITFOR DELAY) untuk mengonfirmasi kondisi — jika halaman memuat lebih lama, kondisi tersebut benar. Metode ini sangat lambat — mengekstrak satu catatan bisa memakan waktu berjam-jam.

python
# Contoh Blind SQL Injection (time-based)
# Jika SQLi rentan, SLEEP(2) dijalankan dengan syarat
import requests
import time

payload = "' OR IF(SUBSTRING((SELECT password FROM users LIMIT 1),1,1)='a',SLEEP(2),0) -- "
url = "http://example.com/user?id=1" + payload

start = time.time()
response = requests.get(url)
elapsed = time.time() - start

# Jika respons datang setelah >2 detik — huruf pertama kata sandi adalah 'a'
print(f"Time: {elapsed:.2f}s - First letter is 'a'" if elapsed > 2 else "First letter is not 'a'")

Out-of-band SQL Injection

Data dikirim bukan melalui respons HTTP, tetapi melalui saluran alternatif: permintaan DNS, permintaan HTTP ke server eksternal, SMTP. Digunakan ketika aplikasi tidak mengembalikan hasil permintaan dan tidak menampilkan kesalahan. MySQL mendukung fungsi LOAD_FILE(), yang dapat memulai permintaan DNS, dan MSSQL — xp_dirtree untuk mengirim data ke server SMB jarak jauh. Out-of-band SQL Injection efektif, tetapi memerlukan pengaturan tambahan di server penyerang dan keberadaan fungsi database tertentu.

Bagaimana cara kerja injeksi SQL?

Mekanisme SQL Injection didasarkan pada kenyataan bahwa SQL menggunakan tanda kutip untuk literal string. Jika aplikasi mensubstitusi input pengguna langsung ke permintaan SQL tanpa escaping, penyerang dapat „menutup” string dan menambahkan kode SQL sembarang. Misalnya, dalam permintaan SELECT * FROM users WHERE name = '$input' substitusi ' OR '1'='1 mengubah permintaan menjadi SELECT * FROM users WHERE name = '' OR '1'='1', yang mengembalikan semua pengguna.

Contoh klasik: melewati autentikasi

Pertimbangkan formulir login dengan permintaan SELECT * FROM users WHERE username = '$user' AND password = '$pass'. Jika penyerang memasukkan di bidang username admin' -- dan membiarkan kata sandi kosong, permintaan yang dihasilkan menjadi SELECT * FROM users WHERE username = 'admin' -- ' AND password = ''. Karakter -- mengomentari sisa permintaan, dan kondisi pemeriksaan kata sandi dinonaktifkan. Server mengembalikan catatan pengguna admin, dan penyerang masuk ke sistem tanpa mengetahui kata sandi.

python
# Contoh SQL Injection — melewati autentikasi
# KODE RENTAN: penggabungan string langsung
def login_vulnerable(username, password):
    query = f"SELECT * FROM users WHERE username='{username}' AND password='{password}'"
    cursor.execute(query)
    return cursor.fetchone() is not None

# username = "admin' --" menonaktifkan pemeriksaan kata sandi
# VERSI AMAN: permintaan terparameterisasi
def login_secure(username, password):
    query = "SELECT * FROM users WHERE username = %s AND password = %s"
    cursor.execute(query, (username, password))
    return cursor.fetchone() is not None

UNION-based: membaca tabel lain

Operator UNION SELECT memungkinkan menggabungkan hasil dua permintaan SELECT. Jika penyerang menemukan parameter yang rentan, ia menambahkan UNION SELECT dengan permintaan dari tabel lain. Contoh: ' UNION SELECT username, password FROM admins --. Syarat keberhasilan — jumlah kolom di kedua permintaan harus cocok. Jumlah kolom ditentukan melalui ORDER BY (substitusi ' ORDER BY 1--, kemudian 2, 3... hingga kesalahan). Mengetahui jumlah kolom, penyerang mensubstitusi UNION SELECT dengan jumlah bidang yang sama.

SQL Injection di aplikasi mobile

Aplikasi mobile menghadapi SQL Injection baik di sisi server (API) maupun di sisi klien — di database lokal (SQLite, Realm). Meskipun risiko SQLi server di API mobile mirip dengan aplikasi web, database lokal menciptakan vektor tambahan. Jika aplikasi menyimpan data di SQLite dan menjalankan permintaan dengan penggabungan string, data berbahaya yang masuk ke database lokal melalui API dapat menyebabkan SQLi saat pemrosesan selanjutnya.

SQL Injection di SQLite di Android/iOS

Database SQLite lokal di perangkat juga rentan terhadap SQL Injection jika aplikasi membentuk permintaan dengan penggabungan string. Content Providers di Android dan Core Data di iOS menggunakan parameterisasi secara default, tetapi permintaan mentah memerlukan perhatian pengembang. SQLite tidak mendukung beberapa permintaan melalui titik koma, yang membatasi kemampuan penyerang, tetapi tidak melindungi dari pembacaan data melalui kondisi WHERE. Selalu gunakan selectionArgs di Android dan NSPredicate dengan parameter di iOS.

SQL Injection melalui API aplikasi mobile

API yang diakses aplikasi mobile sama rentannya dengan server web mana pun. Pengembang mobile sering menganggap SQLi hanya masalah backend, tetapi kerentanan muncul di tingkat endpoint API yang menerima parameter dari klien. Pembagian tanggung jawab tidak melindungi: jika pengembang backend lupa memparameterisasi permintaan, aplikasi mobile pengguna menjadi vektor serangan. Minta backend untuk menggunakan ORM atau prepared statements.

kotlin
// Contoh SQL Injection di SQLite lokal di Android
// KODE RENTAN: penggabungan langsung
fun getUserVulnerable(db: SQLiteDatabase, userId: String): Cursor {
    return db.rawQuery(
        "SELECT * FROM users WHERE id = $userId", null
    )
}

// VERSI AMAN: parameterisasi melalui selectionArgs
fun getUserSecure(db: SQLiteDatabase, userId: String): Cursor {
    return db.rawQuery(
        "SELECT * FROM users WHERE id = ?",
        arrayOf(userId)
    )
}

Metode pencegahan injeksi SQL

Perlindungan terhadap SQL Injection didasarkan pada prinsip sederhana: jangan pernah percaya pada input pengguna dalam permintaan SQL. Satu-satunya metode yang dapat diandalkan — parameterisasi permintaan (prepared statements), di mana kode SQL dan data dikirim secara terpisah. Semua metode lain — escaping, validasi, WAF — adalah lapisan perlindungan tambahan, tetapi tidak menggantikan parameterisasi. Menurut data OWASP (2025), parameterisasi mencegah 100% serangan SQL Injection.

Prepared Statements (permintaan terparameterisasi)

Saat menggunakan prepared statements, permintaan SQL pertama-tama dikompilasi oleh server database tanpa data, kemudian nilai parameter dikirim secara terpisah. Database memperlakukan parameter sebagai data, bukan sebagai kode yang dapat dieksekusi. Bahkan jika penyerang mengirim ' OR '1'='1, database menafsirkannya sebagai nilai string, bukan kode SQL. Prepared statements didukung oleh semua bahasa dan framework modern: PDO di PHP, PreparedStatement di Java, cursor.execute di Python.

Framework ORM dan Query Builder

ORM modern (Hibernate, Entity Framework, SQLAlchemy, Room) secara otomatis menggunakan parameterisasi saat menjalankan permintaan, kecuali jika pengembang beralih ke permintaan mentah. Namun, ORM tidak melindungi sepenuhnya: konstruksi seperti @Query(value = "SELECT * FROM users WHERE name = :name", nativeQuery = true) di JPA memerlukan pengiriman parameter melalui parameter bernama, bukan penggabungan. Query Builder (Knex, jOOQ) juga memparameterisasi permintaan secara default, jika metode mentah tidak digunakan.

Escaping string (tidak direkomendasikan sebagai metode utama)

Escaping karakter khusus (mysql_real_escape_string) — metode usang yang tidak melindungi dari semua jenis SQL Injection. Masalah: escaping tergantung pada pengkodean dan dapat dilewati dengan menggunakan pengkodean multi-byte (misalnya, GBK di sistem Asia). Gunakan escaping hanya dalam kode legacy di mana parameterisasi tidak memungkinkan, dan selalu dikombinasikan dengan validasi ketat tipe data input.

MetodeEfektivitasRekomendasi
Prepared Statements100%Wajib untuk semua permintaan
ORM (penggunaan benar)99%Direkomendasikan
Escaping string70% (tergantung pengkodean)Hanya legacy
Validasi input (daftar putih)50% (hanya untuk angka)Tambahan
WAF (Web Application Firewall)60%Tambahan

Prinsip hak istimewa minimum untuk database

Akun aplikasi harus memiliki hak minimal yang diperlukan: SELECT, INSERT, UPDATE, DELETE — hanya pada tabel yang benar-benar dibutuhkan aplikasi. Larang penggunaan DROP, TRUNCATE, CREATE untuk akun aplikasi. Ini akan membatasi kerusakan bahkan jika SQL Injection berhasil: penyerang tidak akan dapat menghapus tabel atau menjalankan operasi administratif.

Alat untuk mendeteksi injeksi SQL

Pengujian rutin untuk SQL Injection harus menjadi bagian dari pipeline pengembangan aman. Kombinasi analisis statis, pemindaian dinamis, dan pengujian penetrasi manual memberikan hasil terbaik. Menurut Synopsys Cybersecurity Report (2025), pemindai otomatis menemukan hingga 70% kerentanan SQLi, tetapi serangan Blind yang kompleks memerlukan pengujian manual.

  • sqlmap — alat paling populer untuk deteksi dan eksploitasi otomatis SQL Injection
  • OWASP ZAP — pemindai DAST gratis dengan modul pemindaian aktif SQLi
  • Burp Suite Scanner — alat profesional dengan deteksi otomatis SQL Injection
  • SonarQube — analisis kode statis untuk kerentanan, termasuk pola SQLi
  • CodeQL — analisis kode semantik untuk mencari injeksi SQL di sumber

Untuk aplikasi mobile, analisis SQLite lokal juga penting: periksa semua panggilan rawQuery, permintaan ContentProvider, dan permintaan Room dengan rawQuery. Alat: Android Studio Lint (mendeteksi SQLi di SQLite), MobSF (Mobile Security Framework) untuk analisis statis dan dinamis otomatis APK/IPA. Disarankan juga untuk menguji endpoint API melalui sqlmap dengan proxy penyadap lalu lintas aplikasi mobile.

Pertanyaan yang sering diajukan

Apa perbedaan antara SQL Injection dan NoSQL Injection?

SQL Injection menyerang database relasional melalui permintaan SQL. NoSQL Injection memengaruhi database non-relasional (MongoDB, Couchbase) melalui operator permintaan mereka ($gte, $ne, $where). Di MongoDB, injeksi dimungkinkan jika aplikasi membentuk dokumen BSON dari string JSON. Mekanisme perlindungan serupa: parameterisasi dan validasi tipe.

Bagaimana cara mendeteksi SQL Injection dalam kode secara mandiri?

Temukan semua tempat di mana permintaan SQL dibentuk melalui penggabungan string dengan data pengguna. Cari pola seperti "SELECT ... WHERE id = " + userId atau f"UPDATE ... SET name = '{name}'". Setiap string tersebut adalah potensi injeksi SQL. Ganti semuanya dengan permintaan terparameterisasi atau prepared statements.

Apakah ORM secara otomatis melindungi dari SQL Injection?

Framework ORM melindungi secara otomatis hanya jika Anda menggunakan metode Query Builder dan parameter bernama. Jika Anda menggunakan permintaan mentah (nativeQuery di JPA, rawQuery di Room), perlindungan tidak berfungsi — Anda harus mengirim parameter melalui ekspresi yang disiapkan, bukan melalui penggabungan string.

Apa itu Second-Order SQL Injection?

Second-Order SQL Injection adalah serangan di mana data berbahaya disimpan di database sebagai aman tetapi kemudian digunakan dalam permintaan lain tanpa escaping. Misalnya, penyerang mendaftar dengan username ' OR '1'='1. Data disimpan sebagai string — saat pendaftaran tidak ada serangan. Tetapi jika permintaan lain mensubstitusi username ke SQL tanpa parameterisasi, injeksi akan aktif.

Bisakah NoSQL Injection lebih berbahaya daripada SQL Injection?

NoSQL Injection berpotensi lebih berbahaya karena kesadaran pengembang yang lebih rendah. Pengembang tahu tentang SQL Injection dan sebagian besar menggunakan ORM, tetapi hanya sedikit yang tahu tentang NoSQL Injection. Di MongoDB, permintaan yang salah bentuk dapat mengembalikan semua dokumen koleksi. Perlindungan — prepared statements yang sama (parameterisasi BSON) dan validasi ketat data input.

Kesimpulan

  • SQL Injection — serangan injeksi kode SQL melalui parameter pengguna yang tidak di-escape dalam permintaan database
  • Jenis utama — In-band (klasik), Blind (buta, berbasis waktu), Out-of-band (melalui saluran eksternal)
  • Parameterisasi permintaan — satu-satunya metode perlindungan 100% andal terhadap SQL Injection
  • Mitos tentang ORM — ORM hanya melindungi dengan metode bawaan, permintaan mentah dengan penggabungan masih rentan
  • Prinsip hak istimewa minimum — membatasi hak akun database meminimalkan kerusakan saat serangan berhasil
  • Pengujian rutin — sqlmap, OWASP ZAP, SonarQube harus menjadi bagian dari pipeline CI/CD
  • SQLite lokal — aplikasi mobile juga harus memparameterisasi permintaan ke database lokal

Kami akan mengembangkan aplikasi seluler turnkey

IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.

Diskusikan proyek

Baca juga