Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. iOS SDK
Code

Mengamankan Komunikasi di iOS

by
Length:LongLanguages:

Indonesian (Bahasa Indonesia) translation by Kurniawan Sugi Purwanto (you can also view the original English article)

Keamanan selular telah menjadi topik yang panas. Penting bagi tiap aplikasi yang berkomunikasi jarak jauh untuk mempertimbangkan keamanan informasi pengguna yang dikirim melalui suatu jaringan. Di kiriman ini, Anda akan belajar tentang praktek-praktek terbaik untuk mengamankan komunikasi aplikasi iOS Anda di Swift.

Gunakan HTTPS

Ketika mengembangkan suatu aplikasi, pertimbangkan untuk membatasi permintaan jaringan ke yang esensial saja. Untuk berbagai permintaan itu, pastikan dibuat di HTTPS bukan HTTP—ini akan membantu melindungi data pengguna Anda dari "serangan orang yang di tengah", yakni komputer lain di jaringan yang berperan sebagai relai koneksi Anda, tetapi sekaligus menguping atau mengubah data yang melewatinya. Tren dalam beberapa tahun belakangan adalah membuat semua koneksi dengan HTTPS. Untungnya bagi kita, versi Xcode yang terkini telah melakukannya.

Untuk membuat permintaan HTTPS sederhana di iOS, yang dibutuhkan adalah menambahkan "s" ke bagian "http" dari URL. Selama host mendukung HTTPS dan memiliki sertifikat yang valid, kita akan mendapatkan koneksi yang aman. Ini bisa dilakukan untuk API seperti URLSession, NSURLConnection, dan CFNetwork, seperti juga pustaka pihak ketiga yang populer semacam AFNetworking.

App Transport Security

Selama sekian tahun, HTTPS mengalami sejumlah serangan. Karena mengonfigurasi HTTPS dengan benar sangat penting, Apple telah menciptakan App Transport Security (disingkat jadi ATS). ATS memastikan bahwa koneksi aplikasi Anda menggunakan protokol standar industri, jadi Anda tidak akan secara tak sengaja mengirim data pengguna secara tidak aman. Berita baiknya adalah ATS diaktifkan secara default untuk aplikasi yang dibuat dengan versi Xcode saat ini.

ATS tersedia sejak iOS 9 dan OS X El Capitan. Aplikasi yang ada saat ini di store tidak akan secara tiba-tiba mensyaratkan ATS, tetapi berbagai aplikasi sudah dibangun atas versi Xcode yang lebih baru dan SDKnya telah secara default mengaktifkan ATS. Beberapa praktek terbaik yang didukung oleh ATS antara lain penggunaan TLS versi 1.2 atau yang lebih tinggi, meneruskan kerahasiaan melalui pertukaran kunci ECDHE, enkripsi AES-128, dan minimal menggunakan sertifikat SHA-2.

Penting untuk dicatat bahwa meskipun ATS diaktifkan secara otomatis, tidak bisa dipastikan ATS juga dijalankan di aplikasi Anda. ATS bekerja atas dasar kelas seperti URLSession dan NSURLConnection dan antarmuka CFNetwork yang stream-based. ATS tidak diterapkan pada antarmuka jaringan yang levelnya lebih rendah, seperti soket raw, soket CFNetwork, atau pustaka-pustaka pihak ketiga yang menggunakan panggilan-panggilan dengan tingkat lebih rendah ini. Jadi kalau Anda menggunakan jaringan level rendah, Anda harus berhati-hati dalam mengimplementasikan praktek-praktek terbaik ATS secara manual.

Pengecualian ATS

Karena ATS mensyaratkan penggunaan HTTPS dan protokol aman lainnya, mungkin ada bertanya-tanya apakah Anda masih bisa melakukan koneksi jaringan yang tidak mendukung HTTPS, misalnya ketika mengunduh gambar dari suatu cache CDN. Tidak usah khawatir, Anda bisa mengendalikan pengaturan ATS untuk domain-domain khusus di file plist proyek Anda. Di Xcode, temukan file info.plist, klik kanan lalu pilih Open As > Source Code.

Anda akan menemukan bagian yang bernama NSAppTransportSecurity. Jika tidak ada di sana, Anda bisa menambahkan kodenya sendiri; formatnya adalah sebagai berikut.

Dengan ini Anda akan dimungkinkan untuk mengubah pengaturan ATS untuk semua koneksi jaringan. Beberapa pengaturan umum adalah sebagai berikut:

  • NSAllowsArbitraryLoads: Menonaktifkan ATS. Jangan menggunakan ini! Versi Xcode berikutnya akan menghapus kunci ini.
  • NSAllowsArbitraryLoadsForMedia: Memungkinkan pemuatan media tanpa pembatasan ATS untuk framework AV Foundation. Anda hanya bisa mengizinkan pemuatan yang tidak aman jika medianya sudah dienkripsi dengan cara lain. (Tersedia di iOS 10 dan macOS 10.12).
  • NSAllowsArbitraryLoadsInWebContent: Bisa digunakan untuk mematikan pembatasan ATS dari objek tampilan web di aplikasi Anda. Pikirkan terlebih dahulu sebelum mematikan ini karena pengaturan ini memungkinkan pengguna untuk secara paksa memuat konten tidak aman dalam aplikasi Anda. (Tersedia di iOS 10 dan macOS 10.12).
  • NSAllowsLocalNetworking: Ini bisa digunakan untuk mengizinkan resource jaringan lokal dimuat tanpa pembatasan ATS.  (Tersedia di iOS 10 dan macOS 10.12).

Dictionary NSExceptionDomains memungkinkan Anda mengeset pengaturan untuk domain-domain tertentu. Berikut adalah penjelasan terhadap sejumlah kunci penting yang bisa digunakan untuk domain Anda:

  • NSExceptionAllowsInsecureHTTPLoads: Mengizinkan beberapa domain khusus untuk menggunakan koneksi non-HTTPS.
  • NSIncludesSubdomains: Menetapkan apakah aturan tertentu diturunkan ke subdomain.
  • NSExceptionMinimumTLSVersion: Digunakan untuk menetapkan versi TLS yang lebih lama dan kurang aman yang diizinkan.

Perfect Forward Secrecy

Meskipun lalu lintas yang dienkripsi tidak bisa dibaca, tetapi masih mungkin disimpan. Jika kunci privat yang digunakan untuk mengenkripsi lalu lintas itu bisa dikompromikan di masa yang akan datang, kuncinya bisa digunakan untuk membaca semua lalu lintas yang telah disimpan sebelumnya.

Untuk mencegah yang seperti ini, Perfect Forward Secrecy (PFS) menghasilkan kunci sesi yang unik untuk tiap sesi komunikasi. Jika kunci untuk sesi tertentu berhasil dikompromikan, hal itu tak akan membahayakan data dari sesi yang lain. Secara default ATS menerapkan PFS, dan Anda bisa mengendalikan fitur ini dengan menggunakan kunci plist NSExceptionRequiresForwardSecrecy. Dengan mematikan ini TLS akan dimungkinkan untuk menyembunyikan yang tidak mendukung PFS.

Certificate Transparency

Certificate Transparency adalah standar akan datang yang didesain untuk mampu mengecek atau mengaudit sertifikat yang diajukan selama pengaturan awal suatu koneksi HTTPS.

Apabila host Anda menetapkan suatu sertifikat HTTPS, sertifikatnya dikeluarkan oleh Certificate Authority (CA). Certificate Transparency bertujuan untuk melakukan monitoring dekat waktu sesungguhnya untuk menemukan apakah sertifikat dikeluarkan secara jahat atau dikeluarkan oleh otoritas sertifikat yang tidak aman.

Apabila suatu sertifikat dikeluarkan, otoritas sertifikat harus mengirimkan sertifikatnya ke sekian log sertifikat yang append-only, yang selanjutnya bisa dicek silang oleh klien dn diteliti oleh pemilik domain. Sertifikatnya harus ada di setidaknya dua log untuk dianggap valid.

Kunci plist untuk fitur ini adalah NSRequiresCertificateTransparency. Mengaktifkan ini akan menjalankan Certificate Transparency. Tersedia di iOS 10 dan macOS 10.12 atau yang lebih baru.

Certificate dan Public Key Pinning

Apabila Anda membeli sertifikat untuk menggunakan HTTPS di server Anda, sertifikat itu dikatakan absah karena ditandai dengan sertifikat dari otoritas sertifikat intermediate. Sertifikat itu digunakan oleh otoritas intermediate yang mungkin pada gilirannya ditandai oleh otoritas intermediate lainnya, dan seterusnya, selama sertifikat terakhir ditandai oleh otoritas sertifikat root yang terpercaya.

Ketika suatu koneksi HTTPS dipancangkan, sertifikat-sertifikatnya disajikan kepada klien. Rantai kepercayaan ini dievaluasi untuk memastikan sertifikatnya ditandai degan benar oleh otoritas sertifikar yang telah dipercaya oleh iOS. (Ada beberapa cara mem-bypass pengecekan ini dan menerima sertifikat yang Anda tandai sendiri, tetapi jangan melakukan ini dalam suatu environment produksi).

Jika salah satu sertifikat dalam rantai kepercayaan tidak valid, maka keseluruhan sertifikat bisa dikatakan tidak valid dan data Anda tidak akan dikirimkan melalui koneksi yang tidak terpercaya. Meskipun ini sistem yang bagus, tetapi tidaklah kebal pembobolan. Ada berbagai kelemahan yang membuat iOS mempercayai sertifikat penyerang daripada sertifikat yang ditandai secara absah.

Sebagai contoh, proxy pencegat (interception proxy) mungkin memiliki sertifikat intermediate yang terpercaya. Seorang perekayasa balik (reverse engineer) bisa secara manual memerintahkan iOS untuk menerima sertifikat mereka sendiri. Selain itu, kebijakan perusahaan mungkin sudah menyiapkan perangkat untuk menerima sertifikat mereka sendiri. Semua ini mengarah pada kemampuan untuk melakukan serangan "orang di tengah" pada lalu lintas Anda, memungkinkannya untuk dibaca. Tetapi certificate pinning akan mencegah koneksi dilakukan untuk semua skenario di atas.

Certificate pinning akan membantu dengan mengecek sertifikat server terhadap salinan sertifikat yang diekspektasikan.

Untuk mengimplementasikan pinning, delegasi berikut harus diimplementasikan. Untuk URLSession, gunakan kode berikut:

Atau untuk NSURLConnection, Anda bisa menggunakan:

Kedua metode ini memungkinkan Anda mendapatkan objek SecTrust dari challenge.protectionSpace.serverTrust. Karena kita mengabaikan delegasi autentikasi, sekarang kita harus secara eksplisit memanggil fungsi yang menjalankan pengecekan rantai sertifikat standar yang baru saja didiskusikan. Lakukan ini dengan memanggil fungsi SecTrustEvaluate. lalu kita bisa membandingkan sertifikat server dengan yang diekspektasikan.

Berikut suatu contoh implementasi.

Untuk menggunakan kode ini, tetapkan delegasi URLSession ketika membuat koneksi Anda.

Pastikan untuk memasukkan sertifikatnya di paket aplikasi Anda. Jika sertifikatnya berupa file .pem, Anda harus mengonversinya jadi file .cer di terminal macOS:

openssl x509 -inform PEM -in mycert.pem -outform DER -out certificate.cer

Sekarang, jika penyerang mengubah sertifikatnya, aplikasi Anda akan mendeteksinya dan menolak untuk melakukan koneksi.

Perhatikan bahwa sejumlah pustaka pihak ketiga seperti AFNetworking sudah mendukung pinning.

Sanitisasi dan Validasi

Dengan semua proteksi yang ada sejauh ini, koneksi Anda seharusnya sudah cukup aman melawan serangan orang di tengah. Meskipun demikian, satu aturan penting terkait komunikasi jaringan adalah jangan pernah percaya buta pada data yang Anda terima. Kenyataannya, praktek pemrograman yang baik adalah design by contract. Input dan output metode Anda punya kontrak yang menetapkan ekspektasi antarmuka spesifik; jika antarmuka menyatakan akan mengembalikan suatu NSNumber, maka itulah yang seharusnya dilakukan. Jika server Anda mengekspektasikan string 24 karakter atau lebih sedikit maka pastikan antarmuka hanya akan mengembalikan sampai 24 karakter.

Ini akan membantu mencegah kesalahan murni, tetapi yang lebih penting juga akan mengurangi kemungkinan berbagai serangan injeksi dan kerusakan memori. Parser umum seperti kelas JSONSerialization akan mengonversi teks menjadi tipe data Swift yang bisa melakukan tes semacam ini.

Parser lain mungkin bisa bekerja pada objek yang ekivalen dengan Objective-C. Berikut adalah cara validasi apakah tipe suatu objek adalah yang diekspektasikan di Swift.

Sebelum Anda mengirimkan suatu metode delegasi, pastikan objeknya memiliki tipe yang benar sehingga akan merespon metodenya—jika tidak aplikasinya akan crash dengan kesalahan "unrecognized selector".

Selain itu, Anda bisa melihat apakah suatu objek sesuai dengan sebuah protokol sebelum mencoba untuk mengirimkan pesan dengannya:

Atau Anda bisa mengecek apakah sesuai dengan tipe objek Core Foundation.

Sebaiknya pilih dengan cermat informasi apa dari server yang bisa dilihat pengguna. Misalnya, jangan menampilkan peringatan kesalahan yang langsung memasukkan pesan dari server. Pesan kesalahan bisa mengungkap debugging dan informasi terkait keamanan. Salah satu solusi adalah dengan meminta server mengirimkan kode kesalahan khusus yang menyebabkan klien menampilkan pesan yang telah dibuat sebelumnya.

Pastikan juga Anda menyandikan URLnya sehingga hanya berisi karakter-karakter valid. Gunakan stringByAddingPercentEscapesUsingEncoding dari NSString. Meskipun demikian karakter semacam & serta + tidak disandikan, tetapi fungsi CFURLCreateStringByAddingPercentEscapes memungkinkan modifikasi apa saja yang akan disandikan.

Sanitisasi Data Pengguna

Ketika mengirimkan data ke suatu server, jadilah sangat berhati-hati ketika ada input pengguna yang dimasukkan ke perintah yang akan dijalankan oleh suatu server SQL atau server yang akan menjalankan kode. Meskipun mengamankan suatu server terhadap serangan semacam itu ada di luar cakupan artikel ini, sebagai pengembang aplikasi selular kita bisa melakukan bagian kita dengan membuang karakter untuk bahasa yang digunakan server supaya inputnya tidak rawan terkena serangan injeksi perintah. Contoh yang bisa disebutkan di sini mungkin tanda petik satu, titik koma, dan garis miring ketika tidak dibutuhkan untuk masukan pengguna khusus.

Sebaiknya batasi panjang masukan pengguna (user input). Kita bisa membatasi jumlah karakter yang diketik dalam suatu isian teks dengan mengatur delegasi UITextField dan menerapkan metode delegasi shouldChangeCharactersInRange.

Untuk UITextView, metode delegasi untuk menerapkan ini adalah:

Masukan pengguna bisa divalidasi lebih lanjut sehingga masukan tersebut sesuai dengan format yang diharapkan. Sebagai contoh, jika pengguna memasukkan alamat email, kita bisa mengecek alamat yang valid:

Jika seorang pengguna mengunggah gambar ke server, kita bisa memeriksa jika ini adalah gambar yang valid. Sebagai contoh, untuk file JPEG, dua byte pertama dan dua byte terakhir selalu FF D8 dan FF D9.

Daftarnya terus berlanjut, tetapi sebagai pengembang Anda akan tahu apa input (masukan) dan output (keluaran) yang diekspektasikan, terkait persyaratan desainnya.

URLCache

Data yang dikirim melalui jaringan Anda berpotensi untuk di-cache dalam memori dan penyimpanan perangkat. Anda bisa sangat memperkuat proteksi komunikasi jaringan Anda, sebagaimana yang telah kita lakukan, tetapi ternyata komunikasinya ada yang menyimpan.

Adanya berbagai versi iOS mengakibatkan munculnya beberapa perilaku tak terduga ketika berurusan dengan pengaturan cache, dan sejumlah aturan tentang apa yang di-cache di iOS terus berubah di berbagai versi tersebut. Meskipun caching membantu kinerja jaringan dengan mengurangi jumlah permintaan, mematikan atau menghidupkannya untuk data apa saja yang menurut Anda sangat sensitif adalah ide yang bagus. Anda bisa menghapus cache yang dibagikan kapan saja (misalnya saat memulai aplikasi) dengan memanggil:

Untuk menonaktifkan caching di level global, gunakan:

Dan jika Anda menggunakan URLSession, Anda bisa menonaktifkan cache untuk sesi seperti ini:

Jika Anda menggunakan objek NSURLConnection dengan suatu delegasi, Anda bisa menonaktifkan cache per koneksi dengan metode delegasi ini:

Dan untuk membuat permintaan URL yang tidak akan mengecek cache-nya, gunakan:

Berbagai versi iOS 8 memiliki bug yang mengakibatkan beberapa metode mereka sendiri tidak bisa melakukan apapun. Artinya, sebaiknya semua kode di atas diimplementasikan untuk koneksi-koneksi sensitif, jika Anda butuh untuk mengandalkan pencegahan caching permintaan jaringan.

Masa Depan

Penting untuk dipahami adanya batasan HTTPS dalam melindungi komunikasi jaringan.

Dalam banyak kasus, HTTPS berhenti di server. Sebagai contoh, koneksi saya ke server perusahaan mungkin melalui HTTPPS, tetapi begitu sampai di server trafficnya tidak lagi terenkripsi. Artinya perusahaan akan mampu melihat informasi yang dikirimkan (dalam banyak hal perusahaan membutuhkannya), dan itu juga berarti perusahaan bisa mem-proxy atau mengeluarkan lagi informasi tersebut tanpa enkripsi.

Saya tidak bisa menyelesaikan artikel ini tanpa membahas satu konsep lagi yang sekarang sedang tren—yang disebut "end-to-end encryption." Contoh yang bagus adalah aplikasi chat terenkripsi dengan dua perangkat selular yang saling berkomunikasi melalui server. Kedua perangkat tersebut menciptakan kunci publik dan privat—keduanya saling bertukar kunci publik, sedangkan kunci privat tidak pernah meninggalkan perangkat. Data masih dikirim lewat HTTPS melalui server, tetapi sebelumnya data dienkripsi oleh kunci publik pihak lain dengan cara sedemikian rupa sehingga hanya perangkat pemegang kunci privat yang bisa mendekripsi pesan satu sama lain.

Sebagai analogi bagi Anda untuk memahami enkripsi end-to end, bayangkan saya ingin seseorang mengirimkan saya pesan secara aman, hanya saya yang bisa membacanya. Jadi saya memberi suatu kotak dengan gembok yang terbuka (kunci publik) sembari saya tetap menyimpan kunci gemboknya (kunci privat). Pengguna menulis pesan, memasukkannya ke dalam kotak, mengunci gembok, dan mengirimkan balik kepada saya. Hanya saya yang bisa membaca pesan itu karena saya sajalah yang memiliki kunci untuk membuka gembok.

Dengan enkripsi end-to-end, servernya menyediakan layanan untuk komunikasi, tetapi tidak bisa membaca konten komunikasinya—yang dikirimkan adalah kotak terkunci, tetapi mereka tidak punya kunci untuk membukanya. Meskipun detail penerapannya di luar jangkauan artikel ini, konsep ini sangat bagus jika Anda ingin mengizinkan komunikasi yang aman antara pengguna aplikasi Anda.

Jika Anda ingin mempelajari lebih lanjut tentang pendektan ini, mulailah di repo GitHub untuk Open Whisper System, suatu proyek open source.

Kesimpulan

Saat ini hampir semua aplikasi selular akan berkomunikasi melalui suatu jaringan dan keamanan adalah hal yang sangat penting namun seringkali diabaikan dalam pengembangan aplikasi selular.

Di artikel ini, kami membahas sejumlah praktek terbaik pengamanan, termasuk HTTPS sederhana, menerapkan penguatan komunikasi jaringan, sanitisasi data, dan enkripsi end-to-end. Praktek-praktek terbaik tersebut akan bertindak sebagai pondasi keamanan ketika menulis kode untuk aplikasi selular Anda.

Dan senyampang Anda masih di sini, pelajari beberapa tutorial dan kursus aplikasi iOS populer kami!

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.