Apakah ada bahasa pemrograman yang ideal untuk menjadi kuat terhadap hacking?
Dengan kata lain, aplikasi yang dapat di-hack karena patah pelaksanaan, meskipun desain yang sempurna. I'm-tempat ideal untuk mengurangi risiko pengembang salah menerapkan spesifikasi.
Misalnya
Heartbleed tidak akan terjadi jika bahasa yang digunakan bisa menjaga terhadap Buffer Over-Baca.
SQL Suntikan tidak mungkin terjadi jika ada bahasa ditegakkan cara untuk encode/decode data HTML
Data sensitif dapat disimpan ke Pagefiles dalam beberapa bahasa di mana tingkat rendah kontrol aman menghapus memori aren't yang tersedia.
Pointer masalah/meluap lebih sering terjadi di C bila dibandingkan dengan managed code
Numerik kesalahan pembulatan dapat terjadi bila menggunakan pengembang menggunakan salah datatype untuk data yang salah
Denial Of Service serangan mungkin akan berkurang jika aplikasi yang benar adalah multi-threaded
Kode penandatanganan dapat mengurangi ancaman runtime masalah keamanan (link, link)
Pertanyaan
Edit: Banyak dari orang-orang yang dituju buffer-overflow masalah, atau mengatakan bahwa programmer yang bertanggung jawab untuk keamanan. I'm hanya mencoba untuk mendapatkan ide jika tidak ada bahasa yang tujuan utamanya adalah untuk meminjamkan dirinya untuk keamanan sebanyak mungkin dan masuk akal. Artinya, melakukan beberapa bahasa yang memiliki fitur-fitur yang membuat mereka jelas lebih (atau kurang) aman dari kebanyakan bahasa-bahasa lain?
Sebenarnya most bahasa "aman" berkaitan dengan buffer overflows. Apa yang dibutuhkan untuk sebuah bahasa menjadi "aman" dalam hal ini adalah gabungan dari: ketat jenis, sistematis array terikat pemeriksaan, dan manajemen memori otomatis ("garbage collector"). Lihat jawaban ini untuk rincian.
Beberapa bahasa yang tidak "aman" dalam arti bahwa, terutama C (dan C++), dan juga Sebagainya, Fortran... dan, tentu saja, perakitan. Technically, adalah mungkin untuk menulis sebuah implementasi dari C yang akan menjadi "aman" dan masih secara resmi sesuai dengan standar C, tetapi pada harga yang curam (misalnya, anda harus membuat gratis()
tidak ada operasi, jadi dialokasikan memori dialokasikan "selamanya"). Tidak ada yang melakukan itu.
"Aman" bahasa (berkaitan dengan buffer overflows) seperti Java, C#, OCaml, Python, Perl, Pergi, bahkan PHP. Beberapa bahasa ini lebih dari cukup efisien untuk mengimplementasikan SSL/TLS (bahkan pada sistem embedded-saya berbicara dari pengalaman). Sementara itu possible untuk menulis mengamankan kode C, yang dibutuhkan (banyak) konsentrasi dan keterampilan, dan pengalaman yang berulang-ulang menunjukkan bahwa itu adalah sulit, dan bahwa bahkan yang terbaik pengembang tidak bisa berpura-pura bahwa mereka always menerapkan dibutuhkan tingkat konsentrasi dan kompetensi. Ini adalah pengalaman yang merendahkan hati. Pernyataan "don't menggunakan C, itu berbahaya" tidak populer, tidak karena itu akan salah, tetapi, justru sebaliknya, karena hal ini benar: hal ini memaksa pengembang untuk menghadapi gagasan bahwa mereka tidak mungkin para dewa pemrograman yang mereka percaya untuk menjadi, jauh di dalam jiwa mereka.
Catatan, bagaimanapun, bahwa ini "aman" bahasa don't mencegah bug: buffer overflow masih tidak diinginkan mendatang. Tapi mereka mengandung kerusakan: memori luar buffer adalah tidak benar-benar membaca dari atau menulis ke; sebaliknya, menyinggung benang memicu pengecualian, dan (biasanya) dihentikan. Dalam kasus heartbleed, ini akan menghindari bug dari menjadi vulnerability dan itu mungkin telah membantu untuk mencegah skala penuh kepanikan yang kami amati dalam beberapa hari terakhir (tidak ada yang benar-benar tahu apa yang membuat random kerentanan pergi virus seperti sebuah video Youtube yang menampilkan korea terlihat kuda; tapi "logis", jika tidak telah kerentanan sama sekali, maka ini harus dihindari semua ini tragis).
Edit: sejak itu berlimpah dibahas di komentar, saya berpikir tentang masalah yang aman manajemen memori C, dan ada jenis-larutan yang masih memungkinkan gratis()
untuk bekerja, tapi ada cheat.
Satu bisa membayangkan sebuah compiler C yang menghasilkan "lemak pointer". Misalnya, pada mesin 32-bit, membuat pointer 96-bit nilai-nilai. Dialokasikan masing-masing blok akan diberikan yang unik 64-bit identifier (katakanlah, sebuah counter), dan memori internal struktur (hashtable, seimbang pohon...) dipertahankan referensi yang semua blok dengan ID. Untuk setiap blok, panjangnya juga tercatat dalam struktur. Pointer nilai ini maka rangkaian dari blok ID, dan offset dalam blok itu. Ketika pointer diikuti, blok ini terletak oleh ID, offset dibandingkan dengan panjang blok, dan hanya kemudian adalah akses dilakukan. Setup ini memecahkan ganda-dan-setelah-gratis. Hal ini juga mendeteksi most buffer overruns (tapi tidak semua: penyangga dapat menjadi bagian dari suatu struktur yang lebih besar, dan malloc()
/gratis()
manajemen hanya melihat bagian luar blok).
"cheat" adalah "unik 64-bit counter". Hal ini berlaku hanya selama anda don't kehabisan 64-bit integer; di luar itu, anda harus menggunakan kembali nilai-nilai lama. 64 bit harus menghindari masalah itu dalam praktek (ini akan memakan waktu bertahun-tahun untuk "membungkus"), tapi lebih kecil counter (misalnya 32 bit) bisa membuktikan menjadi masalah.
Juga, tentu saja, overhead untuk akses memori dapat menjadi non-diabaikan (cukup beberapa fisik membaca untuk akses masing-masing, meskipun beberapa kasus dapat dioptimalkan jauh), dan dua kali lipat ukuran penunjuk berarti lebih tinggi penggunaan memori, juga, untuk pointer-kaya struktur. Saya tidak menyadari ada compiler C yang menerapkan strategi seperti itu; itu adalah murni teoritis sekarang.
The Ada bahasa dirancang untuk mencegah pemrograman umum kesalahan sebanyak mungkin dan digunakan dalam sistem kritis di mana bug sistem mungkin memiliki konsekuensi bencana.
Beberapa contoh di mana Ada melampaui khas built-in keamanan yang disediakan oleh bahasa-bahasa modern:
Integer type memungkinkan menentukan jangkauan yang diijinkan untuk suatu bilangan bulat. Nilai apapun di luar kisaran ini akan melempar pengecualian (dalam bahasa yang tidak mendukung berbagai jenis, cek manual harus dilakukan).
:=
penugasan =
untuk kesetaraan pemeriksaan. Hal ini untuk menghindari perangkap umum dalam bahasa yang menggunakan =
untuk tugas dan ==
untuk kesetaraan sengaja menugaskan ketika cek kesetaraan dimaksudkan (di Ada, disengaja tugas tidak akan mengkompilasi).
in
dan out
parameter yang menentukan apakah suatu parameter metode yang dapat dibaca atau ditulis
menghindari masalah dengan pernyataan kelompok lekukan tingkat (misalnya, baru-baru ini Apple SSL bug) karena penggunaan end
kata kunci
kontrak (Ada sejak tahun 2012, dan sebelumnya di SPARK subset) memungkinkan metode untuk menentukan prasyarat dan postconditions yang harus satisifed
Ada lebih banyak contoh bagaimana Ada dirancang untuk keamanan yang disediakan di Aman dan Booklet (PDF).
Tentu saja, banyak masalah ini dapat diatasi melalui coding yang tepat style, review kode, unit test, dll. tapi setelah mereka dilakukan di tingkat bahasa berarti bahwa anda mendapatkannya secara gratis.
Hal ini juga perlu menambahkan bahwa meskipun fakta bahwa sebuah bahasa yang dirancang untuk keamanan seperti Ada menghilangkan kelas-kelas banyak bug, masih ada yang menghentikan anda dari memperkenalkan logika bisnis bug bahwa bahasa doesn't tahu apa-apa tentang.
Kebanyakan bahasa pemrograman tingkat yang lebih tinggi dari C yang jauh lebih aman ketika datang untuk kesalahan pemrograman seperti Heartbleed's. Contoh yang terutama untuk mengkompilasi kode mesin termasuk D, Karat dan Ada. It's tidak menarik untuk berbicara tentang memori keselamatan, menurut pendapat saya.
Berikut adalah daftar program-program tambahan fitur bahasa yang (saya pikir) membuatnya jauh lebih sulit untuk menulis kode yang tidak aman. Pertama lima fitur memperluas compiler's kemampuan dalam penalaran tentang kode anda, sehingga anda*, manusia rentan terhadap kesalahan pembuatan, don't harus\. Selain itu, fitur ini juga harus membuat lebih mudah bagi sesama manusia, seorang auditor, untuk alasan tentang kode anda. OpenSSL's source code ini sering digambarkan sebagai kekacauan dan bahasa ketat dari C bisa membantu untuk membuatnya lebih mudah untuk mencari alasan. Dua fitur terakhir adalah tentang konteks isu-isu yang mempengaruhi keamanan juga.
Dari pengetahuan saya yang terbatas bahasa, ada bahasa, tidak semua dari mereka. Karat adalah sebuah contoh dari bahasa yang mencakup banyak - itu adalah ketat, berubah secara default, telah dibatasi unsafety, tidak memerlukan pengumpulan sampah dan cukup performant dan portabel. Waktu kompilasi noda memeriksa dan tergantung jenis saat ini tampak eksotis fitur yang memerlukan tambahan analisis kode statis alat atau bahasa baru, sayangnya.
* Lihat juga: verifikasi formal
Dalam semangat umum dari apa yang anda're bertanya, saya pikir E bahasa ("aman didistribusikan pure-objek platform dan p2p bahasa scripting") yang cukup menarik, dalam hal ini adalah mencoba untuk aman menawarkan fitur/perhitungan model yang umumnya tidak tersedia.
Semua saat ini (berarti masih diperbarui) bahasa pemrograman yang dirancang untuk memiliki beberapa keamanan yang melekat kekurangan sebanyak mungkin, tetapi pada akhir hari it's (hampir selalu) programmer yang bertanggung jawab untuk kelemahan keamanan, bukan bahasa dia's menggunakan.
EDIT: Karena @DCKing menunjukkan, tidak semua bahasa adalah sama, dan I'm tidak mengatakan itu's merupakan ide yang baik untuk memilih salah satu secara acak dan mencoba dan membuatnya bekerja. Saya mengatakan bahwa a (sangat) berbakat C programmer dapat membuat program hanya sebagai aman sebagai semantik yang identik program yang ditulis dalam bahasa tingkat tinggi. Maksud saya adalah bahwa kita harus mengakui bahwa beberapa bahasa membuatnya lebih mudah untuk membuat kesalahan, tetapi juga tahu bahwa pada akhirnya itu's programmer's kesalahan, bukan bahasa's (dengan beberapa pengecualian)
Tidak ada hal seperti mengamankan bahasa. Jika sebuah bahasa yang memberikan keamanan yang cukup untuk masalah anda banyak tergantung pada masalah anda mencoba untuk memecahkan. Seperti jika anda menulis aplikasi web keamanan sebagian besar bahasa yang digunakan dalam konteks ini (misalnya Java, PHP, JavaScript... tambahkan favorit anda) sudah cukup untuk mencegah hal-hal seperti buffer overflows, tetapi bahkan lebih kuat diketik bahasa don't menawarkan melekat dukungan untuk web hal-hal tertentu, misalnya seperti membuat hal itu tidak mungkin atau setidaknya sulit untuk memperkenalkan Cross-Site Scripting bug atau serupa. Dan tidak ada bahasa yang akan melindungi anda terhadap bad trust model, seperti percaya DNS server (DNS rebinding dll), saat ini PKI model atau dengan pihak ketiga (misalnya di luar kendali anda) script ke dalam aplikasi web anda (biasanya iklan atau google analytics).
Sehingga pilihan bahasa yang tepat bisa membantu anda sedikit, tapi tidak ada sihir keamanan pedang.
Ingat bahwa untuk sebagian besar bahasa pemrograman, anda harus khawatir tentang keamanan two bahasa. Ada's bahasa anda're-benar menggunakan, dan kemudian ada's bahasa yang kompilator atau penerjemah tertulis di dalam, yang sering berbeda. (Secara teknis, ada's yang ketiga, yang merupakan pengendali dari CPU itu sendiri.) Masalah keamanan di either dari bahasa-bahasa tersebut dapat membuat program anda tidak aman.
Pertama, anda tidak benar-benar menulis program dalam bahasa pemrograman. Anda menulis petunjuk untuk compiler yang menjelaskan apa jenis program yang anda inginkan, dan compiler menghasilkan sebuah program, dalam cara yang aneh sendiri, yang mudah-mudahan akan (jika anda compiler yang dirancang dengan baik) lakukan hal yang sama bahwa kode sumber anda menjelaskan. Semua program, ketika mereka berjalan, di "bahasa mesin" - mereka adalah serangkaian angka yang ditafsirkan dengan cara tertentu ketika dimuat ke dalam RAM dan diumpankan ke CPU. Bahasa mesin adalah tidak dirancang dengan ketahanan untuk hacking dalam pikiran, sehingga tidak ada bahasa yang dikompilasi dapat benar-benar "kuat" untuk hacking, karena sebenarnya program ini akan di bahasa mesin pula. Salah diartikan atau VM bahasa masih akan berjalan secara native kerangka yang disusun pada akhirnya ke bahasa mesin, sehingga masalah masih berlanjut.
Kedua, yang paling nyata bahasa Turing lengkap. Ini berarti bahwa setiap tugas yang dapat dilakukan oleh salah satu dari mereka dapat dicapai oleh semua. Oleh karena itu, anda tidak dapat membuat "hacking" tidak mungkin (jika hacking berarti menulis program berbahaya); hal itu akan melanggar Turing kelengkapan.
It's bernilai menjelaskan pada titik ini apa yang anda maksud dengan hacking. Karena anda menyebutkan Heartbleed, saya bayangkan anda don't berarti itu di Stallman's akal ("yang menyenangkan bermain-main").
Jika yang anda maksud orang-orang yang menulis program-program yang langsung mengakses memori dan mencuri data, atau mengubah program lain (seperti virus atau keylogger) maka ini bukan masalah bahasa yang benar-benar bisa menangani. Compiler dapat membantu, dengan memiliki fungsi tambahan untuk menghasilkan dikaburkan kode mesin ketika menyusun, tapi pada akhirnya itu's masih mungkin untuk terampil memori hacker untuk menemukan jalan di sekitar. Solusi untuk masalah ini adalah desain OS: sistem operasi harus sandbox program, dan tidak membiarkan satu program untuk main-main dengan memori yang dimiliki program lain. Ini adalah bagian dari apa yang UAC di Windows (meskipun Sandboxie adalah contoh yang lebih baik).
Ada peringatan berikut: Beberapa bahasa, seperti C# atau Java memiliki fitur (lebih tepatnya, compiler dan VM bahwa program yang dijalankan dalam memiliki fitur-fitur) yang memeriksa apakah ada program yang mencoba untuk kotoran di program lain's memori, dan ketika hal ini terjadi melempar kesalahan seperti IllegalAccessException
(misalnya, keylogger.exe
tidak harus mampu membaca Credit_card_number
nilai dari internet banking application.exe
). Tentu saja, hal ini memerlukan menjaga track dari memori apa termasuk untuk program apa, yang memiliki beberapa non-sepele kinerja dan usaha biaya. Beberapa "mudah" bahasa-bahasa seperti C don't memiliki itu - ini adalah mengapa banyak hacks seperti virus yang ditulis dalam C. Saat ini anda harus pintar tentang menghindari UAC, tapi kembali pada hari-hari dari Windows 98 orang bisa melakukan segala macam hal-hal gila untuk komputer/OS dengan membaca dan menulis ke memori mereka weren't harus. Perhatikan bahwa bahkan pada C# anda masih memiliki pilihan untuk menggunakan normal, C-seperti pointer (yang bahasa panggilan tidak aman
dan mengharuskan anda untuk menandai sebagai tersebut dalam kode) jika anda ingin - meskipun CLR akan mungkin berisi hack dalam dirinya sendiri, kecuali jika anda menemukan sebuah lubang keamanan di CLR yang memungkinkan anda untuk terowongan ke sisa memori.
Kedua jenis hacking adalah mengeksploitasi bug dalam program yang sudah ada. Ini adalah kategori heartbleed milik. Dengan ini, pertanyaannya adalah apakah programmer membuat kesalahan atau tidak. Jelas jika bahasa anda adalah sesuatu seperti Brainfuck atau Perl yang sangat sulit untuk membaca, itu lebih mungkin bahwa anda akan membuat kesalahan. Jika itu adalah bahasa dengan banyak "gotcha"s seperti C++ (lihat "klasik" jika (i=1)
vs if (i==1)
atau C kebingungan kontes) maka mungkin akan sulit untuk menangkap kesalahan. Dalam pengertian ini, merancang untuk keamanan adalah benar-benar hanya sepele kasus khusus dari merancang untuk meminimalkan kesalahan programmer.
Perhatikan bahwa bug Heartbleed, baik yang disengaja sabotase atau murni kesalahan, masalah dengan algoritma ** digunakan (penulis "lupa" untuk memeriksa ukuran) - sehingga tidak ada compiler pendek dari AI cerdas sebagai seorang yang sangat pintar, manusia mungkin bisa berharap untuk mendeteksi hal itu, meskipun yang dihasilkan pelanggaran akses dapat dibayangkan bisa tertangkap dengan beberapa pintar manajemen memori.
Ada dua macam kekhawatiran berkaitan dengan hacking:
Ada banyak mengamankan bahasa. Saya akan mengatakan bahwa bahasa dengan manajemen memori dan benang pengaman adalah sebagai aman sebagai bahasa bisa mendapatkan.
Namun, sebagian besar dari mereka adalah tidak efisien. Pengumpulan sampah adalah mahal, dan diartikan bahasa lebih. Dan yang's mengapa aplikasi besar untuk hari ini yang tertulis dalam memori-tidak aman C/C++.
I've baru-baru ini telah bermain dengan Karat, dan bagi saya itu tampaknya menjadi "aman" bahasa dalam arti bahwa itu adalah sebagian dirancang untuk ini.
It's yang dihimpun bahasa seperti C++, dan juga menawarkan petunjuk dan concurrency. (Pengumpul sampah tidak diperlukan)
Namun, itu doesn't lug memori keselamatan pointer dan concurrency dengan itu. Karat adalah bahasa yang doesn't percaya programmer, dan pada waktu kompilasi itu memeriksa mencurigakan penggunaan pointer. Ada beberapa kinds pointer/referensi (dipinjam, dimiliki, dll), dan beberapa dari mereka memiliki aturan ketat tentang mereka. Misalnya, seseorang tidak bisa:
Ada aturan-aturan yang sama yang menjamin keselamatan thread. Jika salah satu keinginan, mereka dapat melewati banyak pemeriksaan ini dengan menggunakan yang tidak aman yang ditandai kotak ("percaya padaku, aku tahu apa yang saya'm melakukan"), atau lambat sampah yang dikumpulkan pointer. Ada juga yang lebih sederhana (dan efisien) cara melakukan ini dengan menggunakan kombinasi klon dan referensi, yang bervariasi seperti penggunaan perubahan.
Dikelola jenis brankas bahasa melakukan banyak hal untuk mencegah hal semacam ini dengan menyediakan validasi dari jenis otomatis dan bergerak eksekusi kode jauh dari CPU itu sendiri, namun yang doesn't mengesampingkan kemungkinan bug dalam pelaksanaan sistem bahasa yang digunakan untuk peta ke CPU (misalnya, CLR dalam .Net atau JVM di Jawa). Hal ini juga doesn't mengesampingkan kemungkinan bug dalam sebuah aplikasi yang bisa menyebabkan hal itu menjadi rentan terhadap manipulasi atau kebocoran data untuk dirinya sendiri.
Mereka meningkatkan keamanan dari sistem yang cukup jauh, tapi mereka juga bulkier, lebih lambat dan lebih terbatas dalam fungsi karena overhead dari mesin eksekusi mereka harus berjalan melalui untuk memberikan fungsi itu.
Tentu saja ada bahasa yang dirancang untuk menjadi aman, tetapi tidak ada yang sempurna. Misalnya, Ada memungkinkan anda untuk menentukan sebuah rentang yang diijinkan untuk integer variabel dan melempar pengecualian jika mereka pernah pergi ke luar kisaran tersebut. Suara yang baik, menyelamatkan anda harus memeriksa secara manual. Masalahnya adalah jika anda don't harus memeriksa secara manual sangat mudah untuk mengatur mekanisme ini dan kemudian lupa untuk mempertimbangkan konsekuensi, yaitu integer dari berbagai pengecualian. Anda baru saja membuat sebuah vektor untuk serangan denial of service.
Keamanan adalah sebuah proses. Bahasa dapat membantu, tapi paling-paling hanya dapat mengurangi kemungkinan kesalahan dalam proses ini biasanya menciptakan baru dan sering bahkan lebih halus. Bisa dibilang C, dengan sifat yang mudah untuk memahami dan sepenuhnya deterministik operasi (tidak ada latar belakang pengumpulan sampah, misalnya), sangat ideal untuk menulis kode yang aman. Dan benar saja, ketika anda melihat banyak keamanan kritis kode ini ditulis dalam C. Untuk menjadi adil untuk Ada, itu lebih tentang keandalan dari keamanan.