
Sebagian besar aplikasi React Native yang “melakukan keamanan” dimulai dengan cara yang sama: instal library seperti jail-monkey, baca beberapa boolean, blokir pengguna jika perangkat terlihat berisiko.
Rasanya seperti perlindungan. Dalam praktiknya, ini hanyalah logging yang dimuliakan. Penyerang yang bertekad dengan Frida, Magisk, atau APK yang ditambal dapat membalik boolean tersebut ke nilai apa pun yang mereka inginkan. Jika logika bisnis Anda mempercayai mereka, Anda kalah.
Tulisan ini memperlakukan klien sebagai musuh dan menjelaskan mengapa deteksi root dan hook adalah kontrol yang lemah dalam lingkungan itu.
Mulai dengan model ancaman
React Native berjalan di dalam proses yang sepenuhnya dikontrol oleh pengguna. Penyerang yang sebenarnya dapat:
Diagram alur yang menunjukkan bagaimana penyerang mengontrol aplikasi
Jika Anda tidak mengasumsikan itu, Anda tidak melakukan pekerjaan keamanan, Anda melakukan teater.
Dari titik itu, beberapa hal harus tidak dapat dinegosiasikan:
- Flag apa pun seperti isRooted, isHooked, isDebugged hanyalah data di dalam proses yang tidak dipercaya
- Kondisional apa pun di JavaScript yang mengatur uang atau hak istimewa dapat dilewati atau ditulis ulang
- Aset sebenarnya ada di backend: akun, pembayaran, promo, tindakan istimewa, API
Mengapa pemeriksaan sisi klien tidak otoritatif
Pola tipikal: instal jail-monkey, kumpulkan objek risiko, bercabang padanya.
import JailMonkey from "jail-monkey";
export function getDeviceRiskSignal() {
return {
isJailBroken: JailMonkey.isJailBroken(),
isDebuggedMode: JailMonkey.isDebuggedMode(),
canMockLocation: JailMonkey.canMockLocation(),
isOnExternalStorage: JailMonkey.isOnExternalStorage(),
hookDetected: JailMonkey.hookDetected(),
};
}
Di tempat lain:
const risk = getDeviceRiskSignal();
if (risk.isJailBroken || risk.hookDetected || risk.isDebuggedMode) {
// Blokir login, pembayaran, atau tampilkan peringatan
}
Di perangkat normal ini “berfungsi.” Di perangkat yang bermusuhan ini hanyalah API yang dikontrol penyerang.
Hook Frida sederhana di Android:
Java.perform(function () {
const JailMonkey = Java.use("com.gantix.JailMonkey.JailMonkeyModule");
JailMonkey.getConstants.implementation = function () {
const original = this.getConstants();
original.put("isJailBroken", false);
original.put("isDebuggedMode", false);
original.put("canMockLocation", false);
original.put("isOnExternalStorage", false);
original.put("hookDetected", false);
return original;
};
});
Untuk detail lebih lanjut contoh Frida melewati semua pemeriksaan, lihat script ini
Jalankan ini di aplikasi dan setiap panggilan ke JailMonkey berbohong demi penyerang. Aplikasi percaya perangkat bersih sementara sepenuhnya diinstrumentasi.
Apa pun yang dihitung murni di perangkat klien adalah input yang tidak dipercaya. Ini dapat berguna sebagai sinyal, tetapi tidak pernah sebagai otoritas akhir untuk tindakan bernilai tinggi.
Pindahkan penegakan ke backend
Jika klien tidak dapat dipercaya, penegakan pindah ke backend. Pemeriksaan klien berhenti menjadi hakim dan menjadi petunjuk.
Untuk alur berisiko tinggi, backend harus menjawab tiga pertanyaan sebelum menyetujui sesuatu yang penting:
- Perangkat dan instance aplikasi apa yang diklaim oleh permintaan ini
- Apakah saluran jaringan cukup terlindungi dari intersepsi dan gangguan
- Apakah permintaan spesifik ini sudah digunakan sebelumnya
Itu dipetakan ke tiga area luas:
- Sinyal integritas perangkat dan aplikasi yang sulit dipalsukan
- Konfigurasi transport yang kuat
- Desain permintaan yang menolak replay
Detailnya berbeda berdasarkan platform dan stack, tetapi arahnya selalu sama. Server memutuskan berdasarkan bukti yang diverifikasi server, bukan pada boolean yang dilaporkan klien.
Pemeriksaan kewarasan red team
Tes mandiri cepat lebih jujur daripada slide deck apa pun.
Ambil build produksi Anda dan:
- Instal di perangkat atau emulator yang di-root atau di-jailbreak
- Lampirkan Frida dan paksa semua flag “risiko” Anda ke nilai aman
- Coba selesaikan login, alur uang, dan alur voucher
Jika semuanya masih berfungsi seperti biasa, maka backend Anda tidak menegakkan apa pun yang penting selain “klien mengatakan itu aman.”
Selanjutnya, simulasikan pengaturan MITM dasar dengan alat proxy seperti Burp Suite:
- Instal sertifikat root kustom di perangkat
- Proxy traffic dan lihat apakah Anda dapat membaca dan mengedit permintaan HTTPS dari aplikasi Anda
Jika traffic sepenuhnya terlihat dan dapat dimodifikasi, keamanan transport lemah dan intersepsi sepele.
Akhirnya:
- Tangkap satu permintaan istimewa yang berhasil
- Replay tanpa melalui UI normal
Jika backend menerimanya lagi, Anda tidak memiliki perlindungan replay yang efektif. Siapa pun yang dapat menangkap satu permintaan valid dapat mengulanginya.
Kesimpulan
Tulisan ini berpendapat untuk berhenti mempercayai klien dan berhenti membiarkannya memutuskan apa yang aman. Pemeriksaan root, pemeriksaan hook, dan library serupa dapat tetap ada, tetapi hanya sebagai sensor berisik yang memberi makan backend, bukan sebagai gerbang di sekitar uang atau hak istimewa.
Pekerjaan sebenarnya ada di sisi server: verifikasi integritas perangkat dan aplikasi dengan attestation, lindungi transport dengan TLS pinning, dan rancang alur sensitif di sekitar perlindungan replay berbasis nonce sehingga permintaan yang ditangkap tidak dapat digunakan kembali.
Tidak ada sistem yang sempurna aman, tetapi tumpukan kontrol ini membuat serangan lebih berisik, lebih kompleks, dan jauh lebih mahal daripada membalik beberapa boolean di klien yang di-hook.