Mengapa pemerintah AS melarang bahasa dinamis untuk proyek yang aman?

120

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 )?

Patrick
sumber
56
Satu-satunya cara untuk mengetahui dengan pasti adalah jika kenalan Anda menanyakan alasannya kepada atasan mereka. Tapi saya bisa mengambil risiko menebak: memeriksa tipe statis adalah lapisan lain yang membantu kebenaran perangkat lunak mission-critical. Tentu saja, itu tidak akan menghilangkan bug, tetapi ini adalah langkah ke arah yang benar: komputer melakukan beberapa pekerjaan untuk Anda. (Ya, saya sadar ini adalah wilayah perang suci).
Andres F.
4
Mungkin relevan: williamedwardscoder.tumblr.com/post/42912076785/…
Robert Harvey
75
Anda tidak ingin perangkat lunak kendali rudal ditulis dalam PHP + JavaScript.
Tulains Córdova
16
Data SDM bukan "tingkat keamanan rendah". Saya berharap perusahaan akan menjaga pekerjaan dan data pribadi saya seaman mungkin.
gbjbaanb
5
@ gbjbaanb Saya kira OP berarti bahwa hilangnya nyawa bukanlah skenario terburuk di sini.
Andres F.

Jawaban:

126

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):

irb(main):001:0> "bar".foo
NoMethodError: undefined method `foo' for "bar":String
        from (irb):1
        from /usr/bin/irb:12:in `<main>'
irb(main):002:0> class String
irb(main):003:1> def foo
irb(main):004:2> "foobar!"
irb(main):005:2> end
irb(main):006:1> end
=> nil
irb(main):007:0> "bar".foo
=> "foobar!"

Apa yang terjadi di sana adalah saya mencoba memanggil metode foodalam konstanta String. Ini gagal. Saya kemudian membuka kelas String dan mendefinisikan metode fooo 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 karena whateverdapat 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:

def mal(&block)
    puts ">:)"
    block.call
    t = block.binding.eval('(self.methods - Object.methods).sample')
    block.binding.eval <<-END
        def #{t.to_s}
          raise 'MWHWAHAW!'
        end
    END
end

class Foo
    def bar
        puts "bar"
    end

    def qux
        mal do
            puts "qux"
        end
    end
end

f = Foo.new
f.bar
f.qux

f.bar
f.qux

Kode ini sepenuhnya terlihat, tetapi malmetodenya bisa di tempat lain ... dan dengan kelas terbuka, tentu saja, dapat didefinisikan ulang di tempat lain.

Menjalankan kode ini:

~ / $ ruby ​​foo.rb 
batang
> :)
qux
batang
b.rb: 20: dalam `qux ': MWHWAHAW! (RuntimeError)
    dari b.rb: 30: in `'
~ / $ ruby ​​foo.rb 
batang
> :)
qux
b.rb: 20: di `bar ': MWHWAHAW! (RuntimeError)
    dari b.rb: 29: in `'

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)

Variabel, metode, nilai diri, dan mungkin blok iterator yang dapat diakses dalam konteks ini semuanya dipertahankan.

Versi lebih pendek yang menunjukkan definisi ulang suatu variabel:

def mal(&block)
    block.call
    block.binding.eval('a = 43')
end

a = 42
puts a
mal do 
  puts 1
end
puts a

Yang mana, ketika dijalankan menghasilkan:

42
1
43

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:

  1. Ruby memungkinkan seseorang untuk mengekstrak lingkungan dari penutupan apa pun
  2. Ruby menangkap semua ikatan dalam lingkup penutupan
  3. Ruby mempertahankan semua binding sebagai hidup dan bisa berubah
  4. Ruby memiliki binding baru yang mengikat binding lama (daripada mengkloning lingkungan atau melarang rebinding)

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? )

Namun, seiring berjalannya waktu, saya menyadari bahwa ada lebih banyak kesulitan dan lebih sedikit daya dengan lingkungan kelas satu daripada yang saya kira sebelumnya. Pada titik ini saya percaya bahwa lingkungan kelas satu tidak berguna yang terbaik, dan paling buruk berbahaya.

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.

Komunitas
sumber
3
Saya tidak mengerti intinya. Anda menyebutkan kelas Perl yang memungkinkan untuk mengubah perilaku skalar. Namun, Perl digunakan secara luas, termasuk di lingkungan yang aman. Hanya memiliki kemampuan ini dalam bahasa tidak berarti bahasa tersebut tidak dapat digunakan. Dalam kasus khusus Ruby, kemungkinan fakta bahwa lingkungan target tidak mendukung Ruby. Secara pribadi, saya belum pernah melihat Ruby tersedia untuk digunakan pada sistem apa pun, dan saya bahkan tidak yakin apakah itu ada pada daftar perangkat lunak yang disetujui.
Thomas Owens
17
@ThomasOwens - Pemahaman saya atas jawaban ini adalah bahwa kuncinya adalah "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.
Bobson
21
Karena tidak memiliki informasi tentang daftar perangkat lunak yang disetujui, saya hanya bisa menebak kesulitan dengan bahasa dinamis. Namun, saya telah melihat masalah serupa dengan perangkat lunak keuangan dan kegagalan industri kartu pembayaran gagal karena bahasa tidak dapat memiliki analisis statis di atasnya untuk masalah keamanan. Saya menunjukkan dua contoh dalam bahasa dinamis di mana sifat bahasa memungkinkannya untuk menumbangkan analisis statis. Saya juga menunjukkan mengapa ini, bahkan secara teoritis, tidak pernah akurat. Mungkin perl diizinkan di beberapa tempat dan bukan di tempat lain, saya hanya bisa menebak alasannya.
2
Anda dapat mendefinisikan kembali fungsi pustaka standar dalam banyak bahasa lain (misalnya Obj-C, C, C ++).
Martin Wickman
12
Yah, .NET metode ekstensi TIDAK sama dengan Ruby di atas. Mereka hanya membuat cara yang lebih mudah untuk mengetik kelas statis. Mereka sebenarnya tidak menambahkan metode ke kelas.
Graham
50

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.

Tagihan
sumber
4
Dan itu hanya positif palsu. Yang benar-benar mengkhawatirkan adalah potensi negatif palsu.
Stephen C
3
Jujur, pengalaman saya dengan alat-alat ini pada umumnya mengerikan. Mungkin sesuatu sepanjang tingkat 1/200 hingga 1/1000 untuk menemukan sesuatu yang benar-benar layak dibahas. Juga, ketika saya mendapatkan false positive yang saya tahu adalah sesuatu yang digunakan di ribuan tempat di basis kode atau kerangka kerja dan hanya mengidentifikasi beberapa kali saya tidak benar-benar dipenuhi dengan kepercayaan diri. Masalahnya adalah bahwa Anda secara efektif menerapkan bukti negatif ketika Anda membangun salah satu alat ini kecuali Anda memulai dengan bahasa formal seperti spec #.
Bill
33

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.

Thomas Owens
sumber
32

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 .

Karena fitur dukungan keamanan yang kritis, sekarang digunakan tidak hanya untuk aplikasi militer, tetapi juga dalam proyek komersial di mana bug perangkat lunak dapat memiliki konsekuensi yang parah, misalnya avionik dan kontrol lalu lintas udara, roket komersial (mis. Ariane 4 dan 5), satelit dan sistem ruang lainnya, transportasi kereta api dan perbankan. Sebagai contoh, perangkat lunak sistem fly-by-wire di Boeing 777 ditulis dalam Ada.

Saya benci mengutip terlalu banyak, tetapi ini menjelaskan dengan sangat baik mengapa bahasa statis (seperti ADA) digunakan untuk proyek-proyek seperti ini:

Sejumlah besar pemeriksaan waktu kompilasi didukung untuk membantu menghindari bug yang tidak akan terdeteksi hingga waktu berjalan dalam beberapa bahasa lain atau akan membutuhkan pemeriksaan eksplisit untuk ditambahkan ke kode sumber. Sebagai contoh, sintaks memerlukan penutupan blok yang diberi nama secara eksplisit untuk mencegah kesalahan karena token yang tidak cocok. Ketaatan pada pengetikan yang kuat memungkinkan deteksi banyak kesalahan perangkat lunak yang umum (parameter yang salah, pelanggaran kisaran, referensi yang tidak valid, tipe yang tidak cocok, dll.) Baik selama waktu kompilasi, atau sebaliknya selama waktu pengoperasian. Karena concurrency adalah bagian dari spesifikasi bahasa, kompiler dalam beberapa kasus dapat mendeteksi kebuntuan potensial. Compiler juga biasanya memeriksa pengidentifikasi salah eja, visibilitas paket, deklarasi redundan, dll. Dan dapat memberikan peringatan dan saran berguna tentang cara memperbaiki kesalahan.

Ada juga mendukung pemeriksaan waktu berjalan untuk melindungi terhadap akses ke memori yang tidak dialokasikan, kesalahan buffer overflow, pelanggaran jangkauan, kesalahan off-by-one, kesalahan akses array, dan bug lain yang terdeteksi. Pemeriksaan ini dapat dinonaktifkan untuk kepentingan efisiensi runtime, tetapi seringkali dapat dikompilasi secara efisien. Ini juga termasuk fasilitas untuk membantu verifikasi program. Untuk alasan ini, Ada banyak digunakan dalam sistem kritis, di mana anomali dapat menyebabkan konsekuensi yang sangat serius, misalnya, kematian karena kecelakaan, cedera, atau kerugian finansial yang parah. Contoh sistem di mana Ada digunakan termasuk avionik, kereta api, perbankan, militer dan teknologi ruang angkasa.

Manajemen memori dinamis Ada tingkat tinggi dan jenis aman. Ada tidak memiliki "pointer" generik (dan tidak jelas); juga tidak secara implisit menyatakan tipe pointer apa pun. Sebagai gantinya, semua alokasi dan deallokasi memori dinamis harus dilakukan melalui tipe akses yang dinyatakan secara eksplisit. Setiap jenis akses memiliki kumpulan penyimpanan terkait yang menangani detail manajemen memori tingkat rendah; programmer dapat menggunakan kumpulan penyimpanan default atau menentukan yang baru (ini sangat relevan untuk Non-Uniform Memory Access). Bahkan dimungkinkan untuk mendeklarasikan beberapa tipe akses berbeda yang semuanya menunjuk tipe yang sama tetapi menggunakan kumpulan penyimpanan yang berbeda. Juga, bahasa menyediakan untuk pemeriksaan aksesibilitas, baik pada waktu kompilasi dan pada waktu berjalan, yang memastikan bahwa nilai akses tidak dapat hidup lebih lama dari jenis objek yang ditunjuknya.

Michael Jasper
sumber
3
"Karena fitur dukungan kritis-keselamatan Ada, sekarang [digunakan dalam] roket komersial (misalnya Ariane 4 dan 5)" , tentu saja Ariane 5 pertama meledak karena bug perangkat lunak , sehingga tidak ada peluru perak.
Andrew Marshall
5
@AndrewMarshall: "Meskipun laporan mengidentifikasi bug perangkat lunak sebagai penyebab langsung, peneliti lain melihat penyebabnya sebagai kegagalan desain sistem dan masalah manajemen" - Saya sangat meragukan bahwa kode yang ditulis dalam bahasa yang berbeda (misalnya Java atau C ++) akan mendapatkan roket ke orbit.
Martin Schröder
@ MartinSchröder Oh saya tidak meragukan bahwa Ada kemungkinan masih lebih unggul daripada yang lain untuk aplikasi ini, hanya mencatat bahwa itu bukan bukti yang bodoh. Bahasa lain mungkin membiarkan bug yang tak terhitung jumlahnya yang tidak mungkin ada di Ada.
Andrew Marshall
13

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.

Is this the government being slow to adopting new technologies?

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.

Sulthan
sumber
2
IMHO, lebih banyak bug telah "ditelan" oleh buffer overflow yang tidak terdeteksi daripada yang lain, yang merupakan sesuatu yang tidak bisa dibolehkan oleh sebagian besar bahasa paling dinamis ... hanya mengatakan
miraculixx
@miraculixx Benar, ada alasan mengapa Java / C # dan bahasa sejenis lebih banyak digunakan daripada Ruby. Mereka defensif - mereka memeriksa semuanya. Dalam C / C ++ defensif dapat ditegakkan dengan menggunakan standar pengkodean yang baik. Anda juga dapat memberlakukan cek untuk semuanya. Tetapi bisakah Anda membayangkan menulis aplikasi sensitif dalam ruby ​​atau javascript? Kemungkinan untuk bug tersembunyi sangat bagus.
Sulthan
Memang saya bisa. Kami mungkin setuju bahwa perangkat lunak perlu diuji secara menyeluruh, terlepas dari bahasa pemrograman. Untuk menghindari regresi, pengujian sebaiknya dilakukan secara otomatis menggunakan misalnya pengujian unit, BDD et al. Menganggap pendekatan profesional (aplikasi sensitif, kan?), Mencapai cakupan tes yang memadai adalah proses yang dikelola, tidak dibiarkan kebetulan. Dengan itu, saya ragu bahwa C / C ++, Java memiliki keunggulan dibandingkan suka ruby ​​atau javascript dalam hal bug tersembunyi. Keterampilan pemrogram? Mungkin lebih teknis dengan C ++, ragu dengan Java, namun hampir tidak masalah bahasa. Lebih teknis! = Kualitas produk.
miraculixx
6

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:

-      foreach ($data as $i => $value) {
+      foreach (array_values($data) as $i => $value) {

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 $idalam $i => $valueharus 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 $iharus 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 array IEnumerable, sulit untuk membangun kode yang akan mengacaukan kunci kamus dengan indeks array seperti ini bahkan dengan sengaja, apalagi tanpa sengaja.

Roman Starkov
sumber
2

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: masukkan deskripsi gambar di sini

Martin Wickman
sumber
18
-1 Ada banyak alasan teknis yang valid mengapa suatu bahasa akan dipilih daripada yang lain (waktu nyata, pengetikan statis, pemeriksaan waktu berjalan) untuk sistem yang kritis terhadap keselamatan. Anda menyiratkan bahwa alasannya adalah 100% budaya, kami vs. mereka, dan sewenang-wenang, yang IMO sama sekali tidak benar dalam kasus ini.
Michael Jasper
8
"Bahasa tidak aman atau tidak aman" - lihat stackoverflow.com/a/14313277/602554 . Beberapa bahasa pasti "lebih aman" daripada yang lain.
Michael Jasper
2
Memperbarui jawaban saya, mungkin sesuai dengan keinginan Anda. Saya masih percaya bahwa seberapa aman suatu sistem itu lebih tergantung pada kode yang Anda tulis daripada bahasa apa yang Anda gunakan, meskipun beberapa bahasa membantu menghindari masalah tertentu (sementara, mungkin memperkenalkan yang lain).
Martin Wickman
2
@ MartinWickman: a) Suntikan SQL / HTML dan buffer overflows diselesaikan oleh beberapa sistem tipe - Anda memiliki tipe yang berbeda untuk input yang lolos dan tidak dihilangkan sehingga Anda tahu mana yang harus diperlakukan dengan cara apa. b) tidak semua masalah keamanan dalam 'proyek aman' harus berarti kompromi. Saya tidak ingin perangkat lunak yang menjalankan pesawat memiliki bug apa pun meskipun itu bukan masalah 'keamanan' (yaitu tidak dapat digunakan untuk mengambil alih sistem).
Maciej Piechotka
5
-1 untuk masalah akurasi faktual. Eksploitasi buffer overflow adalah masalah yang sangat spesifik untuk bahasa C; Anda tidak pernah mendengar tentang mereka dalam bahasa yang tidak memungkinkan Anda mengalokasikan buffer string pada stack. Dan sama sekali tidak sulit untuk membayangkan dialek SQL hipotetis di mana penggunaan Parameter tidak hanya diizinkan tetapi diperlukan . Injeksi SQL tidak mungkin dilakukan dalam bahasa ini. Jadi ya, bahasa yang dirancang dengan baik dapat melindungi Anda dari beberapa jenis serangan umum.
Mason Wheeler
2

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.

Andrew Medico
sumber