Semua artikel
// Artikel

Review Keamanan Android App Links dan Deep Links

Dipublikasikan 8 Juli 2026

Deep link Android adalah input navigasi yang dikendalikan penyerang. Custom scheme dapat diklaim lebih dari satu aplikasi; HTTPS App Link menambah association terverifikasi antara domain web dan paket Android yang ditandatangani. Keduanya tidak membuktikan URI, akun, ID objek, atau aksi yang diminta aman. Pisahkan kontrol routing dari otorisasi.

Inventaris rute lebih dulu

Baca setiap intent filter VIEW, lalu catat scheme, host, aturan path, kategori, activity tujuan, dan aksi setelah parsing. App Links memerlukan VIEW, DEFAULT, dan BROWSABLE; android:autoVerify="true" meminta Android memverifikasi host web yang memenuhi syarat. Buat cakupan host dan path sengaja sempit. Handler /orders/* tidak boleh menerima /admin/* karena pola luas dipilih demi kemudahan.

<activity android:name=".OrderLinkActivity" android:exported="true">
  <intent-filter android:autoVerify="true">
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:scheme="https" android:host="shop.example.test" android:pathPrefix="/orders" />
  </intent-filter>
</activity>

Activity harus mem-parsing data secara defensif. Tolak scheme, host, bentuk path, nama query ganda, pemisah terenkode, ID hilang, dan perintah pengubah state yang tidak diikuti konfirmasi terautentikasi. Otorisasi server tetap menentukan apakah pengguna boleh membaca order 42; kecocokan rute klien tidak memberi hak itu.

Verifikasi association domain

Publikasikan Digital Asset Links JSON pada lokasi HTTPS tepat https://shop.example.test/.well-known/assetlinks.json. Gunakan fingerprint penandatanganan release, bukan debug. Review setiap package dan sertifikat karena masing-masing adalah relationship yang diizinkan.

[{
  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": {
    "namespace": "android_app",
    "package_name": "com.example.shop",
    "sha256_cert_fingerprints": ["AA:BB:CC:...:FF"]
  }
}]

Ambil path tanpa redirect; periksa JSON valid, nama package, fingerprint sertifikat, dan seluruh host produksi. Android 12 ke atas umumnya mengirim web link belum terverifikasi ke browser; link terverifikasi dapat membuka aplikasi, sementara preferensi pengguna tetap dapat mengubah perilaku. Jangan menyebut verifikasi membuat input aplikasi tepercaya.

Uji perilaku aplikasi terpasang

Uji resolver umum dan peluncuran dengan package eksplisit. Catat output, versi aplikasi, API perangkat, URI, layar yang muncul, pengguna terautentikasi, serta bukti jaringan.

adb shell am start -a android.intent.action.VIEW \
  -c android.intent.category.BROWSABLE \
  -d "https://shop.example.test/orders/42?tab=receipt" \
  com.example.shop
adb shell pm get-app-links com.example.shop

Ulangi dengan host salah, path salah, id ganda, nilai kosong, pemisah percent-encoded, ID objek milik pengguna lain, sesi kedaluwarsa, dan action link dari aplikasi lain. Lulus berarti penolakan aman atau login normal lalu rute terotorisasi. Crash, aksi istimewa diam-diam, atau disclosure adalah gagal.

Catatan review

ArtefakBuktiPemilikHasilPengecualianRemediasi
Filter manifestmerged manifest releasepemilik Androidlulus/gagalrute publik disetujuipersempit host/path
File associationrespons HTTPS dan fingerprint releasepemilik weblulus/gagalhost stagingpublikasikan JSON tepat
Parser URIkasus adb negatifpemilik aplikasilulus/gagalformat lama terdokumentasiparser allowlist
Akses tujuanuji objek asingpemilik APIlulus/gagaltidak adaotorisasi server

Aturan keputusan: App Link boleh memilih layar. Link tidak boleh melewati autentikasi, otorisasi objek, konfirmasi transaksi, atau validasi input.

Remediasi dan uji ulang

Hapus filter tak didukung, gunakan HTTPS App Links untuk rute milik web, jauhkan custom scheme dari handoff sensitif, dan pusatkan validasi URI sebelum navigasi. Perbaiki data association di sumber saat signing release berubah. Uji ulang fresh install dan update karena state verifikasi serta pilihan pengguna memengaruhi hasil. Pengujian mobile dapat menghubungkan bukti manifest, domain, runtime, dan backend.

Simpan bukti berisi nomor build, digest sertifikat signing, extract manifest, respons association yang diunduh, URI uji, versi perangkat, waktu, dan hasil yang diharapkan. Tetapkan pemilik aplikasi untuk perbaikan parser serta pemilik web untuk perbaikan file domain. Tandai pengecualian hanya bila rute bisnis terdokumentasi memerlukan scope lebih luas, memiliki tanggal kedaluwarsa, dan uji otorisasi kompensasi lulus. Buka kembali item gagal setelah release candidate mengonfirmasi perubahan pada perangkat.

Verifikasi praktik dan penutupan

Gunakan perangkat uji terisolasi serta build yang ditandatangani untuk release. Rekam respons association dengan curl -i --max-redirs 0 https://shop.example.test/.well-known/assetlinks.json; hasil yang diharapkan ialah HTTP 200, content type application/json, tanpa redirect, dan satu target dengan nama package serta fingerprint SHA-256 yang cocok dengan metadata release. Respons 301, halaman login HTML, digest sertifikat lama, atau entri package debug adalah artefak web gagal, walaupun browser tampak membuka aplikasi.

Lalu jalankan adb shell pm get-app-links com.example.shop. Output yang diharapkan menunjukkan shop.example.test terverifikasi bagi package yang terpasang; simpan output mentah, bukan hanya label status dalam laporan. Luncurkan setiap URI disetujui tanpa package eksplisit untuk menguji pemilihan resolver, lalu dengan package untuk menguji parser. Untuk https://shop.example.test/orders/42?id=43, perilaku yang diharapkan adalah penolakan sebelum navigasi karena ambiguitas tidak boleh diselesaikan dari urutan parameter. Bagi pengguna yang tidak berhak atas order 42, hasilnya harus sama seperti navigasi normal di aplikasi, tanpa data order sempat tampil.

Tutup review hanya setelah snapshot manifest, hash respons HTTPS, output perangkat, hasil URI diterima dan ditolak, serta trace otorisasi backend merujuk build sama. Rotasi signing, migrasi host, perluasan path, atau pembaruan Android dapat membatalkan verifikasi; buka ulang bukti terdampak, jangan memindahkan status hijau lama.

Bukti resolver

Jalankan adb shell pm verify-app-links --re-verify com.example.shop sebelum membaca state association saat ini. Output package yang diharapkan mencantumkan domain terkonfigurasi sebagai verified; state numerik atau belum terverifikasi memerlukan pemeriksaan respons host, sertifikat package, konektivitas perangkat, dan preferensi link pengguna. Simpan output command bersama versi Android. Jangan menandai parser lulus dari hasil verifikasi saja: association package dan otorisasi rute adalah pengujian berbeda.

Pemeriksaan akhir menguji domain terverifikasi, route valid, route tidak sah, dan intent dari aplikasi lain pada perangkat target. Output diharapkan: resolver dan aplikasi hanya membuka tujuan yang diotorisasi. Kasus tepi: user memilih browser sebagai default atau association belum diperbarui; catat state perangkat. Tutup setelah bukti resolver dan validasi parser menunjukkan batas sama.

Sources

Punya sistem yang perlu diuji?