Saya kenal beberapa orang yang saat ini mengerjakan proyek militer AS (tingkat keamanan rendah, data jenis sumber daya manusia non-tempur).
Keadaan awal dari kode proyek diserahkan kepada militer untuk ditinjau, dan mereka menjalankan program melalui semacam alat penganalisa keamanan. Itu mengembalikan laporan masalah keamanan yang diketahui dalam kode dan diperlukan perubahan yang perlu diimplementasikan sebelum pengiriman produk akhir.
Salah satu item yang perlu diselesaikan adalah penghapusan bagian dari proyek yang ditulis dalam Ruby karena itu adalah bahasa yang dinamis.
Apa latar belakang / alasan untuk tidak memungkinkan bahasa dinamis digunakan dalam pengaturan yang aman? Apakah ini pemerintah yang lambat mengadopsi teknologi baru? Atau apakah bahasa dinamis menimbulkan risiko keamanan tambahan dibandingkan dengan bahasa statis (ala C ++ atau Java )?
Jawaban:
Ada sejumlah hal 'rapi' yang dapat dilakukan dalam bahasa dinamis yang dapat disembunyikan di bagian-bagian kode yang tidak segera jelas bagi programmer atau auditor lain mengenai fungsionalitas potongan kode yang diberikan.
Pertimbangkan urutan ini dalam irb (shell ruby interaktif):
Apa yang terjadi di sana adalah saya mencoba memanggil metode
foo
dalam konstanta String. Ini gagal. Saya kemudian membuka kelas String dan mendefinisikan metodefoo
o return"foobar!"
, dan kemudian menyebutnya. Ini berhasil.Ini dikenal sebagai kelas terbuka dan memberi saya mimpi buruk setiap kali saya berpikir untuk menulis kode di ruby yang memiliki keamanan atau integritas. Tentu itu memungkinkan Anda melakukan beberapa hal dengan sangat cepat ... tapi saya bisa membuatnya jadi setiap kali seseorang menyimpan string, menyimpannya ke file, atau mengirimnya melalui jaringan. Dan ini sedikit mendefinisikan kembali String dapat terselip di mana saja dalam kode.
Banyak bahasa dinamis lainnya memiliki hal serupa yang dapat dilakukan. Perl memiliki Tie :: Scalar yang dapat di belakang layar mengubah cara kerja skalar yang diberikan (ini sedikit lebih jelas dan membutuhkan perintah khusus yang dapat Anda lihat, tetapi skalar yang dikirimkan dari tempat lain bisa menjadi masalah). Jika Anda memiliki akses ke Perl Cookbook, cari Resep 13.15 - Membuat Variabel Ajaib dengan dasi.
Karena hal-hal ini (dan yang lain sering menjadi bagian dari bahasa dinamis), banyak pendekatan untuk analisis statis keamanan dalam kode tidak berfungsi. Perl dan Undecidability menunjukkan hal ini sebagai kasus dan menunjukkan bahkan masalah sepele seperti itu dengan sintaksis menyoroti (
whatever / 25 ; # / ; die "this dies!";
menimbulkan tantangan karenawhatever
dapat didefinisikan untuk mengambil argumen atau tidak pada saat runtime benar-benar mengalahkan stabilo sintaksis atau penganalisa statis).Ini bisa menjadi lebih menarik di Ruby dengan kemampuan untuk mengakses lingkungan tempat penutupan ditentukan (lihat YouTube: Menjaga Ruby Reasonable dari RubyConf 2011 oleh Joshua Ballanco). Saya menyadari video ini dari komentar Ars Technica oleh MouseTheLuckyDog .
Pertimbangkan kode berikut:
Kode ini sepenuhnya terlihat, tetapi
mal
metodenya bisa di tempat lain ... dan dengan kelas terbuka, tentu saja, dapat didefinisikan ulang di tempat lain.Menjalankan kode ini:
Dalam kode ini, penutupan dapat mengakses semua metode dan binding lainnya yang didefinisikan di kelas pada lingkup itu. Itu mengambil metode acak dan mendefinisikannya kembali untuk memunculkan pengecualian. (lihat kelas Binding di Ruby untuk mendapatkan gagasan tentang apa yang dapat diakses oleh objek ini)
Versi lebih pendek yang menunjukkan definisi ulang suatu variabel:
Yang mana, ketika dijalankan menghasilkan:
Ini lebih dari kelas terbuka yang saya sebutkan di atas yang membuat analisis statis tidak mungkin. Apa yang ditunjukkan di atas adalah bahwa penutupan yang dilewatkan di tempat lain, disertai dengan lingkungan penuh yang telah didefinisikan. Ini dikenal sebagai lingkungan kelas satu (seperti ketika Anda dapat melewati fungsi, mereka adalah fungsi kelas satu, ini adalah lingkungan dan semua ikatan yang tersedia pada saat itu). Seseorang dapat mendefinisikan kembali variabel apa pun yang didefinisikan dalam ruang lingkup penutupan.
Baik atau buruk, mengeluh tentang ruby atau tidak (ada kegunaan di mana seseorang ingin bisa mendapatkan di lingkungan metode (lihat Aman di Perl)), pertanyaan "mengapa ruby akan dibatasi untuk proyek pemerintah "Benar-benar dijawab dalam video yang ditautkan di atas.
Mengingat bahwa:
Dengan implikasi dari empat pilihan desain ini, tidak mungkin untuk mengetahui apa yang dilakukan sedikit kode.
Lebih lanjut tentang ini dapat dibaca di blog Abstract Heresies . Pos khusus adalah tentang Skema di mana perdebatan semacam itu terjadi. (terkait pada SO: Mengapa Skema tidak mendukung lingkungan kelas satu? )
Saya harap bagian ini menunjukkan aspek bahaya dari lingkungan kelas satu dan mengapa Ruby diminta untuk menghapus dari solusi yang disediakan. Bukan hanya karena Ruby adalah bahasa dinamis (seperti yang disebutkan-jawab lain, bahasa dinamis lain telah diizinkan dalam proyek lain), tetapi ada masalah khusus yang membuat beberapa bahasa dinamis semakin sulit dipikirkan.
sumber
"many approaches to static analysis of security in code doesn't work"
, jadi ditolak karena tidak dapat dianalisis (setidaknya oleh grup ini). Apakah saya menafsirkannya dengan benar, atau apakah itu alasan yang sah untuk menolaknya, saya tidak tahu.Dengan asumsi evaluasi itu hanya keamanan, dan bukan hanya pemindaian penerimaan (yaitu, mereka tidak menerima Ruby karena mereka tidak ingin mendukung Ruby) kemudian:
Alat analisis keamanan biasanya memiliki waktu yang buruk dengan perilaku dinamis.
Sebagai contoh:
Jalankan proyek .NET apa pun yang ditulis dengan fitur-fitur modern seperti ASP.NET MVC dan Entity Framework melalui sesuatu seperti Veracode dan lihat daftar cucian positif palsu apa yang Anda terima dalam laporan Anda.
Veracode bahkan mencantumkan banyak teknik dasar dalam pustaka inti .NET 4 sebagai "kerangka kerja yang tidak didukung" sebagai tidak didukung atau hanya beta meskipun sebagian besar sudah berusia beberapa tahun pada saat ini.
Jika Anda berurusan dengan entitas yang memiliki ketergantungan kuat pada alat seperti itu, mereka hampir dipaksa untuk mempertimbangkan ketidakamanan tersebut jika mereka tidak memiliki keahlian teknis, dan sumber daya, untuk mengevaluasi proyek secara manual dan melihat apakah itu ditulis dengan benar dan aman.
Dalam operasi sipil di mana sistem komputer umumnya tidak mengontrol apa pun yang berbahaya atau sangat mahal mitigasi adalah bahwa Anda mendiskusikan positif palsu dan mereka umumnya diterima dalam jumlah besar.
Dalam operasi perbankan Anda masih memiliki peluang untuk mitigasi positif palsu, tetapi Anda akan menghabiskan lebih banyak waktu untuk membahas hal-hal kecil dari setiap item. Ini dengan cepat menjadi penghalang biaya dan Anda mulai menggunakan metode yang lebih tradisional.
Dalam militer, penerbangan, industri berat dan sejenisnya, sistem dapat mengontrol hal-hal yang memiliki mode kegagalan yang mengerikan sistem tersebut sehingga mereka mungkin memiliki aturan yang sangat ketat tentang bahasa, kompiler, dll.
Organisasi juga umumnya menulis kebijakan keamanan mereka untuk kasus terburuk yang mereka ketahui, jadi bahkan jika Anda menulis sesuatu yang sepele, jika Anda menulisnya untuk organisasi yang memiliki sistem non-sepele, standar umumnya adalah menahannya standar yang lebih tinggi kecuali seseorang meminta pengecualian khusus.
sumber
Bahasa dinamis dapat digunakan dalam aplikasi pertahanan dan militer. Saya pribadi menggunakan dan mengirim Perl dan Python di aplikasi DoD. Saya juga melihat PHP dan JavaScript digunakan dan digunakan. Dalam pengalaman saya, sebagian besar kode non-kompilasi yang saya lihat adalah skrip shell dan Perl karena lingkungan yang diperlukan disetujui dan diinstal pada berbagai sistem target yang mungkin.
Fakta bahwa bahasa-bahasa ini dinamis kemungkinan besar bukan masalah. Penerjemah untuk bahasa-bahasa ini harus disetujui untuk digunakan pada sistem target. Jika penerjemah tidak disetujui untuk digunakan (atau, mungkin, benar, tetapi tidak digunakan pada sistem target), maka bahasa tidak dapat digunakan. Menggunakan penerjemah yang diberikan (atau aplikasi apa pun) pada sistem yang aman memerlukan sejumlah rintangan keamanan: analisis sumber, kemampuan untuk mengkompilasi dari sumber untuk lingkungan target, analisis tambahan dari binari, memastikan tidak ada konflik dengan infrastruktur yang ada, dll.
sumber
Saya menghabiskan beberapa waktu mewawancarai DOD (Departemen Pertahanan), untuk posisi menulis kode untuk MMU F-16 . Tanpa melanggar non-pengungkapan: MMU adalah unit komputer yang mengontrol hampir semua fungsi F-16. Sangat penting bahwa tidak ada kesalahan, seperti bug run-time, terjadi selama penerbangan. Sama pentingnya bahwa sistem melakukan operasi komputasi real-time.
Untuk alasan ini dan alasan historis lainnya, semua kode untuk sistem ini ditulis atau dikompilasi ke ADA, bahasa pemrograman berorientasi objek statis .
Saya benci mengutip terlalu banyak, tetapi ini menjelaskan dengan sangat baik mengapa bahasa statis (seperti ADA) digunakan untuk proyek-proyek seperti ini:
sumber
Baik DoD dan NASA memiliki sejarah panjang dengan pemrograman gagal yang menelan biaya miliaran dolar. Kedua institusi telah menerima proses yang seharusnya melindungi mereka dari mengulangi kesalahan yang sama.
Ini adalah kesalahpahaman - bahasa dinamis bukan teknologi baru, mereka cukup lama. Masalahnya adalah bahwa jika Anda pernah memiliki masalah yang disebabkan oleh bahasa dinamis (mis. Oleh pengetikan yang lemah / dinamis) dan masalah itu menghabiskan banyak uang, Anda bisa menerima kebijakan yang akan mencegah Anda melakukan kesalahan yang sama lagi - misalnya melarang penggunaan bahasa dinamis dalam sistem sensitif.
Bahasa dinamis akan sering "menelan" bug dan berakhir dengan beberapa perilaku tak terduga. Ini sangat berbahaya dalam sistem sensitif. Jika terjadi kesalahan, Anda ingin mengetahuinya sesegera mungkin.
Jika keamanan terkait, perlu untuk melihat use case yang sebenarnya. Sebagai contoh, saya tidak berpikir bahwa halaman web Ruby on Rails akan secara otomatis kurang aman daripada halaman web Java.
sumber
Saya ingin menambahkan jawaban yang ada dengan menjelaskan SA-CORE-2014-005 Drupal , yang merupakan kerentanan sangat kritis yang memungkinkan injeksi SQL dan akhirnya eksekusi kode arbitrer. Ini disebabkan oleh aturan pengetikan dinamis dan lax runtime mengetik PHP.
Keseluruhan tambalan untuk masalah ini adalah:
Kode ini adalah bagian dari lapisan abstraksi SQL yang dirancang untuk mencegah injeksi SQL. Dibutuhkan query SQL dengan parameter bernama, dan array asosiatif yang memberikan nilai untuk setiap parameter bernama. Nilai diizinkan menjadi array, untuk kasus-kasus seperti
WHERE x IN (val1, val2, val3)
, di mana ketiga nilai dapat diteruskan sebagai nilai array tunggal untuk parameter bernama tunggal.Kerentanan terjadi karena kode berasumsi bahwa
$i
dalam$i => $value
harus indeks integer nilai. Ia melanjutkan dan menyatukan "indeks" ini langsung ke dalam query SQL sebagai bagian dari nama parameter, karena integer tidak perlu keluar, kan?Sayangnya untuk Drupal, PHP tidak memberikan jaminan seperti itu. Dimungkinkan untuk meneruskan array asosiatif lain, yang kuncinya adalah string, dan loop ini akan dengan senang hati menggabungkan kunci string ke dalam query, sebagaimana adanya (ingat kode berpikir itu hanya bisa menjadi bilangan bulat).
Meskipun ada cara untuk memiliki kesalahan yang sama dalam bahasa yang diketik secara statis, mereka tidak mungkin. Pengembang yang baik akan mempertimbangkan hal
$i
- hal apa yang mungkin terjadi sebelum menggabungkannya ke dalam kueri. Dengan bahasa yang diketik secara statis, sangat mudah untuk menerapkan yang$i
harus berupa bilangan bulat, dan dalam kode sensitif keamanan seperti ini, itu pasti akan dilakukan.Selain itu, kode tersebut benar-benar memeriksa apakah nilainya adalah array sebelum mengulangi item. Dan di sinilah letak bagian kedua dari kegagalan yang memungkinkan kerentanan ini: array asosiatif dan array "normal" menghasilkan true
is_array
. Walaupun benar juga bahwa dalam C #, baik kamus dan arrayIEnumerable
, sulit untuk membangun kode yang akan mengacaukan kunci kamus dengan indeks array seperti ini bahkan dengan sengaja, apalagi tanpa sengaja.sumber
Apakah basis kode aman atau tidak tergantung pada bagaimana Anda menulis kode Anda, bagaimana Anda mengujinya dan bagaimana Anda memvalidasi dan memantau pengembangan dan proses penerapan Anda. Bahasa tidak aman atau tidak aman, itu adalah bagaimana Anda kode.
Sebagian besar insiden keamanan karena input berbahaya (injeksi sql, buffer overflows), virus, rootkit, dan trojan. Tidak ada bahasa yang dapat melindungi Anda dari hal itu.
Jadi melarang kelas bahasa sebagai "tidak aman" bukan alasan yang sah.
Saya menduga seseorang, karena alasan apa pun - diberi tahu atau tidak - memutuskan untuk melarang bahasa-bahasa ini. Setelah beberapa saat, itu menjadi kebenaran organisasi . Mungkin memang benar pada saat itu untuk beberapa proyek, tetapi budaya kontrol tidak tertarik pada perubahan keputusan (mengakui mereka salah) dan lebih suka aturan sederhana. Mereka berkembang dengan baik pada peraturan dan regulasi dan tidak masalah apakah itu masuk akal atau tidak, itu adalah anggapan keselamatan yang diperhitungkan.
Ini terjadi sepanjang waktu dalam budaya kontrol. Saya melihatnya kurang lebih setiap hari. Tidak masuk akal, tapi begitulah. Jika Anda ingin membaca lebih lanjut tentang topik yang sangat relevan ini, saya merekomendasikan buku Schneider " Alternatif Reengineering ". Berikut adalah diagram budaya oleh Michael Sahoto / Agilitrix , berdasarkan buku Schneider:
sumber
Sejauh yang saya tahu, kebijakan resmi Departemen Pertahanan pada umumnya tidak melarang bahasa yang dinamis.
Standar untuk perangkat lunak yang dikembangkan atau dibeli oleh Departemen Pertahanan diumumkan secara resmi oleh Badan Sistem Informasi Pertahanan (DISA). Keamanan Aplikasi mereka - Keamanan Aplikasi & Keamanan Implementasi Panduan Implementasi Teknis (STIG) tidak melarang bahasa tertentu. Itu tidak menyebutkan Ruby, tetapi menyebutkan Perl dan Python yang juga dinamis. Itu menyebutkan mereka dalam konteks berbagai topik (mengikuti Standar Pengkodean yang ditetapkan, menghindari Kerentanan Injeksi Perintah, dll).
Mungkin yang Anda lihat adalah alat pemindaian yang terlalu ketat (ada beberapa yang berbeda yang disebutkan dalam STIG, masing-masing mungkin memiliki interpretasi sendiri dari aturan) dan / atau interpretasi yang terlalu ketat dari hasilnya.
sumber