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

Mengamankan Coding di Swift 4

by
Difficulty:IntermediateLength:LongLanguages:

Indonesian (Bahasa Indonesia) translation by Ilham Saputra (you can also view the original English article)

Dari meminimalkan penggunaan pointer ke tipe pengecekan yang kuat pada waktu kompilasi, Swift adalah bahasa yang bagus untuk pengembangan yang aman. Tetapi itu berarti Anda tergoda untuk melupakan keamanan sama sekali. Masih ada kerentanan, dan Swift juga menarik bagi pengembang baru yang belum belajar tentang keamanan.

Tutorial ini adalah panduan pengkodean yang aman yang akan membahas perubahan dalam Swift 4 serta opsi perkakas baru yang tersedia di Xcode 9 yang akan membantu Anda mengurangi kerentanan keamanan.

Pointer dan Overflows

Banyak kerentanan keamanan telah berputar di sekitar C dan penggunaan pointer. Ini karena pointer memungkinkan Anda mengakses lokasi memori mentah, sehingga lebih mudah untuk membaca dan menulis ke area yang salah. Ini telah menjadi cara utama bagi penyerang untuk mengubah program jahat.

Swift kebanyakan tidak menggunakan pointer, tetapi masih memungkinkan Anda untuk berinteraksi dengan C. Banyak API, termasuk seluruh Core Foundation API Apple, seluruhnya didasarkan pada C, jadi sangat mudah untuk memperkenalkan penggunaan pointer kembali ke Swift.

Untungnya, Apple telah menamai jenis penunjuk dengan tepat: UnsafePointer<T>, UnsafeRawPointer<T>, UnsafeBufferPointer<T>, dan UnsafeRawBufferPointer. Akan tiba saatnya ketika API yang Anda gunakan akan mengembalikan jenis ini, dan aturan utama saat menggunakannya adalah tidak menyimpan atau mengembalikan pointer untuk digunakan nanti. Sebagai contoh:

Karena kami mengakses penunjuk di luar penutupan, kami tidak tahu pasti apakah penunjuk masih menunjuk ke konten memori yang diharapkan. Cara aman untuk menggunakan penunjuk dalam contoh ini adalah dengan menyimpannya, bersama dengan pernyataan cetak, dalam penutupan.

Penunjuk ke string dan array juga tidak memiliki batasan pemeriksaan. Ini berarti mudah untuk menggunakan penunjuk tidak aman pada larik tetapi secara tidak sengaja mengakses di luar batasnya—buffer overflow.

Kabar baiknya adalah Swift 4 mencoba untuk merusak aplikasi daripada melanjutkan apa yang disebut perilaku tidak terdefinisi. Kami tidak tahu apa yang ditunjukkan oleh buffer[5]! Namun, Swift tidak akan menangkap setiap kasus. Atur breakpoint setelah kode berikut dan lihat variabel a dan c. Mereka akan diatur ke 999.

Ini menunjukkan stack overflow karena tanpa alokasi eksplisit, variabel umumnya disimpan di stack.

Pada contoh berikut, kami membuat alokasi dengan kapasitas hanya satu Int8. Alokasi disimpan di heap, jadi baris berikutnya akan melimpah. Untuk contoh ini, Xcode hanya memperingatkan Anda dengan catatan di konsol gets tidak aman.

Jadi, apa cara terbaik untuk menghindari overflows? Ini sangat penting ketika berinteraksi dengan C untuk melakukan pemeriksaan batas pada input untuk memastikannya dalam jangkauan.

Anda mungkin berpikir bahwa itu cukup sulit untuk diingat dan menemukan semua kasus yang berbeda. Jadi untuk membantu Anda, Xcode hadir dengan alat yang sangat berguna bernama Address Sanitizer.

Pembersih Alamat telah diperbaiki dalam Xcode 9. Ini adalah alat yang membantu Anda menangkap akses memori yang tidak valid seperti contoh yang baru saja kita lihat. Jika Anda akan bekerja dengan Unsafe* jenis, itu adalah ide yang baik untuk menggunakan alat pembersih alamat. Itu tidak diaktifkan secara default, jadi untuk mengaktifkannya, pergi ke Product > Scheme > Edit Scheme > Diagnostics, dan cek Address Sanitizer. Di Xcode 9 ada sub-opsi baru, Deteksi penggunaan stack setelah return. Opsi baru ini mendeteksi kerentanan use-after-scope dan use-after-return dari contoh pertama kami.

Terkadang diabaikan adalah integer overflow. Ini karena integer overflow adalah lubang keamanan hanya ketika digunakan sebagai indeks atau ukuran buffer, atau jika nilai tak terduga dari overflow mengubah aliran kode keamanan kritis. Swift 4 menangkap integer overflow yang paling jelas pada waktu kompilasi, seperti ketika angka tersebut jelas lebih besar dari nilai maks integer.

Sebagai contoh, berikut ini tidak akan dikompilasi.

Tetapi banyak kali jumlah akan tiba secara dinamis saat runtime, seperti ketika pengguna memasukkan informasi dalam UITextField. Perilaku tidak didefinisikan Sanitizer adalah alat baru di Xcode 9 yang mendeteksi integer overflow yang ditandatangani dan bug jenis-ketidakcocokan lainnya. Untuk mengaktifkannya, pergi ke Product > Scheme > Edit Scheme > Diagnostics, dan menyalakan Undefined Behavior Sanitizer. Kemudian dalam Build Settings > Undefined Behavior Sanitizer. atur Enable Extra Integer Checks ke Yes.

Ada hal lain yang perlu disebutkan tentang perilaku tidak terdefinisi. Meskipun Swift murni menyembunyikan pointer, referensi, dan salinan buffer masih digunakan di belakang layar, jadi Anda bisa mengalami perilaku yang tidak Anda harapkan. Misalnya, ketika Anda memulai iterasi atas indeks koleksi, indeks secara tidak sengaja dapat dimodifikasi oleh Anda selama iterasi.

Di sini kita hanya menyebabkan array numbers untuk menunjuk ke array baru di dalam loop. Lalu apa gunanya number? Ini biasanya disebut referensi menggantung, tetapi dalam kasus ini Swift secara implisit membuat referensi ke salinan buffer dari array Anda selama durasi loop. Itu berarti bahwa pernyataan cetak benar-benar akan mencetak 1, 2, dan 3 bukannya 1, 4, 5.... Ini bagus! Swift menyelamatkan Anda dari perilaku tidak terdefinisi atau crash aplikasi, meskipun Anda mungkin tidak mengharapkan output itu juga. Pengembang rekan Anda tidak akan berharap koleksi Anda dimutasikan selama enumerasi, jadi secara umum, ekstra hati-hati selama penghitungan bahwa Anda tidak mengubah koleksi.

Jadi Swift 4 memiliki penegakan keamanan yang besar pada waktu kompilasi untuk menangkap kerentanan keamanan ini. Ada banyak situasi di mana kerentanan tidak ada sampai waktu berjalan ketika ada interaksi pengguna. Swift juga mencakup pengecekan dinamis, yang dapat menangkap banyak masalah pada waktu proses juga, tetapi terlalu mahal untuk dilakukan di seluruh utas sehingga tidak dilakukan untuk kode multithread. Pemeriksaan dinamis akan menangkap banyak tetapi tidak semua pelanggaran, jadi masih penting untuk menulis kode aman di tempat pertama!

Dengan itu, mari kita beralih ke area lain yang sangat umum untuk kerentanan—serangan injeksi kode.

Injeksi dan Serangan String Format

Serangan string format terjadi ketika string input diuraikan dalam aplikasi Anda sebagai perintah yang tidak Anda maksud. Sementara string Swift murni tidak rentan terhadap serangan string format, kelas Objective-C NSString dan Core Foundation CFString adalah, dan mereka tersedia dari Swift. Kedua kelas ini memiliki metode seperti stringWithFormat.

Katakanlah pengguna dapat memasukkan teks acak dari UITextField.

Ini bisa menjadi lubang keamanan jika string format ditangani langsung.

Swift 4 mencoba untuk menangani argumen string format yang hilang dengan mengembalikan 0 atau NULL, tetapi ini terutama menjadi perhatian jika string akan diteruskan kembali ke runtime Objective-C.

Sementara sebagian besar waktu cara yang salah hanya akan menyebabkan crash, penyerang dapat dengan hati-hati menyusun string format untuk menulis data ke lokasi memori tertentu pada stack untuk mengubah perilaku aplikasi Anda (seperti mengubah variabel isAuthenticated).

Pelaku besar lainnya adalah NSPredicate, yang dapat menerima string format yang digunakan untuk menentukan data apa yang diambil dari Core Data. Klausul seperti LIKE dan CONTAINS memungkinkan wildcard dan harus dihindari, atau setidaknya hanya digunakan untuk pencarian. Idenya adalah untuk menghindari penghitungan akun, misalnya, di mana penyerang memasukkan "a*" sebagai nama akun. Jika Anda mengubah LIKE clause menjadi ==, ini berarti string secara harfiah harus sesuai dengan "a*".

Serangan umum lainnya terjadi dengan mengakhiri string input lebih awal dengan karakter kutipan tunggal sehingga perintah tambahan dapat dimasukkan. Misalnya, login dapat dilewati dengan memasukkan ') OR 1=1 OR (password LIKE '* ke dalam UITextField. Baris tersebut diterjemahkan menjadi "di mana kata sandi seperti apa saja", yang mengabaikan otentikasi sama sekali. Solusinya adalah untuk sepenuhnya menghindari setiap upaya injeksi dengan menambahkan tanda kutip ganda Anda sendiri dalam kode. Dengan begitu, setiap tanda kutip tambahan dari pengguna dilihat sebagai bagian dari string input alih-alih karakter terminating khusus:

Satu lagi cara untuk melindungi diri dari serangan ini adalah dengan hanya mencari dan mengecualikan karakter tertentu yang Anda tahu bisa berbahaya dalam string. Contohnya termasuk kutipan, atau bahkan titik dan garis miring. Sebagai contoh, adalah mungkin untuk melakukan serangan traversal direktori ketika input dilewatkan langsung ke kelas FileManager. Dalam contoh ini, pengguna memasukkan "../" untuk melihat direktori induk dari jalur alih-alih sub-direktori yang dimaksud.

Karakter khusus lainnya mungkin termasuk NULL terminating byte jika string digunakan sebagai string C. Pointer ke string C membutuhkan NULL terminating byte. Karena ini, dimungkinkan untuk memanipulasi string hanya dengan memperkenalkan byte NULL. Penyerang mungkin ingin mengakhiri string lebih awal jika ada bendera seperti needs_auth=1, atau ketika akses diaktifkan secara default dan dimatikan secara eksplisit seperti dengan is_subscriber=0.

Mengurai string HTML, XML, dan JSON juga membutuhkan perhatian khusus. Cara paling aman untuk bekerja dengan mereka adalah dengan menggunakan pustaka asli Foundation yang menyediakan objek untuk setiap node, seperti kelas NSXMLParser. Swift 4 memperkenalkan serialisasi tipe-aman ke format eksternal seperti JSON. Tetapi jika Anda membaca XML atau HTML menggunakan sistem khusus, pastikan bahwa karakter khusus dari input pengguna tidak dapat digunakan untuk memerintahkan penerjemah.

  • < harus menjadi &lt.
  • > harus diganti dengan &gt.
  • & harus menjadi &amp.
  • Dalam nilai-nilai atribut, apapun " atau ' perlu menjadi &quot dan &apos, masing-masing.

Berikut ini contoh cara cepat untuk menghapus atau mengganti karakter tertentu:

Area terakhir untuk serangan injeksi ada di dalam penangan URL. Periksa untuk memastikan input pengguna tidak digunakan secara langsung di dalam penangan URL khusus openURL dan didReceiveRemoteNotification. Verifikasi URL adalah apa yang Anda harapkan dan itu tidak memungkinkan pengguna untuk secara sembarangan memasukkan informasi untuk memanipulasi logika Anda. Misalnya, alih-alih membiarkan pengguna memilih layar mana dalam tumpukan untuk menavigasi ke berdasarkan indeks, hanya izinkan layar tertentu menggunakan pengenal buram, seperti t=es84jg5urw.

Jika Anda menggunakan WKWebViews di aplikasi Anda, mungkin bagus untuk memeriksa URL yang akan dimuat di sana juga. Anda dapat mengesampingkan decisionPolicyFor navigationAction, yang memungkinkan Anda memilih jika Anda ingin melanjutkan dengan permintaan URL.

Beberapa trik webview yang dikenal termasuk memuat skema URL kustom pengembang tidak berniat, seperti app-id: untuk meluncurkan aplikasi atau sms: yang sama sekali berbeda untuk mengirim teks. Perhatikan bahwa tampilan web tertanam tidak menampilkan bilah dengan alamat URL atau status SSL (ikon kunci), sehingga pengguna tidak dapat menentukan apakah sambungannya tepercaya.

Jika tampilan web adalah layar penuh, misalnya, URL dapat dibajak dengan halaman web yang terlihat seperti layar masuk Anda kecuali mengarahkan kredensial ke domain jahat. Serangan lain di masa lalu termasuk serangan skrip lintas situs yang telah membocorkan cookie dan bahkan seluruh sistem file.

Pencegahan terbaik untuk semua serangan yang disebutkan adalah meluangkan waktu untuk mendesain antarmuka Anda menggunakan kontrol UI asli alih-alih hanya menampilkan versi berbasis web dalam aplikasi Anda.

Sejauh ini, kita telah melihat jenis serangan yang relatif mudah. Tapi mari kita akhiri dengan serangan yang lebih maju yang dapat terjadi di runtime.

Runtime Hacking

Sama seperti Swift menjadi lebih rentan ketika Anda berinteraksi dengan C, berinteraksi dengan Objective-C membawa kerentanan terpisah ke meja.

Kami telah melihat masalah dengan NSString dan memformat serangan string. Hal lain adalah bahwa Objective-C jauh lebih dinamis sebagai bahasa, memungkinkan jenis dan metode longgar untuk diedarkan. Jika kelas Swift Anda mewarisi dari NSObject, maka itu menjadi terbuka untuk serangan runtime Objective-C.

Kerentanan yang paling umum melibatkan penukaran dinamis metode keamanan penting untuk metode lain. Misalnya, metode yang mengembalikan jika pengguna divalidasi dapat ditukarkan dengan metode lain yang hampir selalu mengembalikan nilai true, seperti isRetinaDisplay. Meminimalkan penggunaan Objective-C akan membuat aplikasi Anda lebih kuat terhadap jenis serangan ini.

Di Swift 4, metode pada kelas yang mewarisi dari kelas Objective-C hanya terkena runtime Objective-C jika metode atau kelas itu sendiri ditandai dengan @attribute. Seringkali fungsi Swift dipanggil sebagai gantinya, bahkan jika atribut @objc digunakan. Ini bisa terjadi ketika metode memiliki atribut @objc tetapi tidak pernah benar-benar dipanggil dari Objective-C.

Dengan kata lain, Swift 4 memperkenalkan lebih sedikit inferensi @objc, jadi ini membatasi permukaan serangan dibandingkan dengan versi sebelumnya. Namun, untuk mendukung fitur runtime, biner Objective-C-based perlu menyimpan banyak informasi kelas yang tidak bisa dilucuti. Ini cukup untuk merekayasa balik untuk membangun kembali antarmuka kelas untuk mencari tahu bagian keamanan apa yang harus diperbaiki, misalnya.

Di Swift, ada lebih sedikit informasi yang terpapar dalam biner, dan nama fungsi dihapus. Namun, mangling dapat dibatalkan oleh alat Xcode dengan cepat. Bahkan, fungsi Swift memiliki skema penamaan yang konsisten, yang menunjukkan apakah masing-masing adalah fungsi Swift atau tidak, bagian dari kelas, nama modul dan panjang, nama kelas dan panjang, nama metode dan length, atribut, parameter, dan jenis return.

Nama-nama ini lebih pendek di Swift 4. Jika Anda khawatir tentang reverse engineering, pastikan versi rilis simbol strip aplikasi Anda dengan pergi ke Build Settings > Deployment > Strip Swift Symbols dan atur opsi ke Yes.

Selain mengaburkan kode keamanan kritis, Anda juga dapat memintanya untuk menjadi sebaris. Ini berarti bahwa setiap tempat yang disebut fungsi dalam kode Anda, kode akan diulang di tempat itu, bukan hanya ada di satu lokasi biner.

Dengan cara ini, jika penyerang berhasil melewati pemeriksaan keamanan tertentu, itu tidak akan mempengaruhi kejadian lain dari cek yang terletak di tempat lain dari kode Anda. Setiap cek harus ditambal atau disangkutkan, membuatnya jauh lebih sulit untuk berhasil melakukan retakan. Anda dapat menyisipkan kode seperti ini:

Kesimpulan

Berpikir tentang keamanan harus menjadi bagian besar dari pembangunan. Hanya berharap bahasa yang aman dapat menyebabkan kerentanan yang bisa dihindari. Swift populer untuk pengembangan iOS, tetapi tersedia untuk aplikasi desktop macOS, tvOS, watchOS, dan Linux (sehingga Anda dapat menggunakannya untuk komponen sisi server di mana potensi untuk mengeksekusi eksekusi kode jauh lebih tinggi). App sandboxing dapat rusak, seperti dalam kasus perangkat jailbroken yang memungkinkan kode tidak ditandatangani untuk dijalankan, jadi penting untuk tetap memikirkan keamanan dan memperhatikan pemberitahuan Xcode saat Anda melakukan debug.

Tip terakhir adalah memperlakukan peringatan kompilator sebagai kesalahan. Anda dapat memaksa Xcode untuk melakukan ini dengan pergi ke Build Settings dan pengaturan Treat Warnings as Errors ke Yes. Jangan lupa untuk memodernisasi pengaturan proyek Anda saat bermigrasi ke Xcode 9 untuk mendapatkan peringatan yang ditingkatkan, dan yang tak kalah pentingnya, manfaatkan fitur-fitur baru yang tersedia dengan mengadopsi Swift 4 hari ini!

Belajar Swift

Kami telah membuat panduan lengkap untuk membantu Anda mempelajari Swift, apakah Anda baru saja memulai dengan dasar-dasar atau Anda ingin menjelajahi topik yang lebih canggih.

Untuk primer pada aspek lain dari pengkodean aman untuk iOS, periksa beberapa posting saya yang lain di sini di Envato Tuts+!

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.