Pertanyaan saya berkaitan dengan keamanan JavaScript.
Bayangkan sebuah sistem otentikasi tempat Anda menggunakan kerangka kerja JavaScript seperti Backbone atau AngularJS , dan Anda membutuhkan titik akhir yang aman. Itu bukan masalah, karena server selalu memiliki kata terakhir dan akan memeriksa apakah Anda berwenang untuk melakukan apa yang Anda inginkan.
Tetapi bagaimana jika Anda membutuhkan sedikit keamanan tanpa melibatkan server? Apakah itu mungkin?
Misalnya, Anda memiliki sistem perutean sisi klien dan Anda ingin rute konkret dilindungi untuk pengguna yang masuk. Jadi Anda melakukan ping ke server menanyakan apakah Anda diizinkan untuk mengunjungi rute yang dilindungi dan Anda melanjutkan. Masalahnya adalah ketika Anda melakukan ping ke server, Anda menyimpan respons dalam sebuah variabel, jadi lain kali Anda pergi ke rute pribadi, itu akan memeriksa bahwa jika Anda sudah masuk (tidak ada ping ke server), dan tergantung pada respon itu akan pergi atau tidak.
Seberapa mudah bagi pengguna untuk memodifikasi variabel itu dan mendapatkan akses?
Pengetahuan keamanan (dan JavaScript) saya tidak bagus. Tetapi jika variabel tidak dalam lingkup global dan berada di bagian pribadi dari pola modul yang hanya memiliki getter tetapi tidak setter, bahkan dalam kasus itu, dapatkah Anda meretasnya?
sumber
manipulate any part of the sight without long lines
situs vs sightJawaban:
Silakan baca jawaban Joachim sebelum membaca yang ini. Ia membahas alasan umum di balik kerentanan sisi klien. Sekarang, untuk saran bagaimana Anda bisa mengatasi masalah ini ...
Skema aman untuk komunikasi klien-server tanpa harus mengautentikasi dengan server secara manual pada setiap permintaan:
Anda masih membiarkan server mengatakan yang terakhir, dan server masih harus memvalidasi semua yang dikatakan klien, tetapi itu terjadi secara transparan.
Asumsikan protokol HTTPS untuk mencegah serangan man-in-the-middle (MITMA).
Jabat tangan klien dengan server untuk pertama kalinya, dan server menghasilkan kunci publik untuk klien dan menyimpan kunci pribadi menggunakan skema enkripsi asimetris. Klien menyimpan kunci "publik" server di penyimpanan lokal, dienkripsi dengan kata sandi aman yang tidak Anda simpan di mana pun.
Klien sekarang offline. Klien ingin melakukan tindakan tepercaya. Klien memasukkan kata sandi dan mengambil kunci publik server.
Klien sekarang melakukan tindakan berdasarkan pengetahuannya tentang data itu, dan klien mengenkripsi setiap tindakan yang dilakukannya dengan kunci publik server untuk klien itu .
Ketika klien sedang online, klien mengirimkan ID kliennya dan semua tindakan yang dilakukan klien dikirim ke server dienkripsi dengan kunci publik server.
Server mendekripsi tindakan, dan jika mereka dalam format yang benar percaya bahwa itu berasal dari klien.
catatan:
Anda tidak dapat menyimpan kata sandi klien di mana pun, jika tidak seorang penyerang akan dapat mengambil kunci dan menandatangani tindakan sebagai miliknya. Keamanan skema ini hanya bergantung pada integritas kunci yang dihasilkan server untuk klien. Klien masih perlu diautentikasi dengan server ketika meminta kunci itu.
Anda sebenarnya masih mengandalkan server untuk keamanan dan bukan klien. Setiap tindakan yang dilakukan klien Anda harus memvalidasi di server.
Dimungkinkan untuk menjalankan skrip eksternal pada pekerja web . Ingatlah bahwa setiap permintaan JSONP yang Anda miliki sekarang merupakan masalah keamanan yang jauh lebih besar. Anda harus melindungi kunci di semua biaya. Setelah Anda kehilangan itu, seorang penyerang dapat menyamar sebagai pengguna.
Ini memenuhi permintaan Anda bahwa 'tidak ada ping ke server' dilakukan. Seorang penyerang tidak bisa begitu saja meniru permintaan HTTP dengan data palsu jika mereka tidak tahu kuncinya.
Jawaban Joachim masih benar . Faktanya, Anda masih melakukan semua otentikasi di server . Satu-satunya hal yang Anda simpan di sini adalah perlunya validasi kata sandi dengan server setiap saat. Anda sekarang hanya perlu melibatkan server ketika Anda ingin melakukan, atau menarik data yang diperbarui. Yang kami lakukan di sini adalah menyimpan kunci tepercaya di sisi klien dan meminta klien untuk memvalidasinya kembali.
Ini adalah skema yang cukup umum untuk aplikasi satu halaman (misalnya, dengan AngularJS).
Saya menyebut kunci publik server "publik" karena apa artinya dalam skema seperti RSA , tetapi sebenarnya informasi sensitif dalam skema dan harus dilindungi.
Saya tidak akan menyimpan kata sandi di mana pun dalam memori. Saya akan membuat pengguna mengirimkan kata sandi 'offline' setiap kali dia mulai menjalankan kode offline.
Jangan memutar kriptografi Anda sendiri - gunakan perpustakaan yang dikenal seperti Stanford untuk otentikasi.
Terima nasihat ini apa adanya . Sebelum Anda memutar otentikasi semacam ini di aplikasi penting bisnis dunia nyata, berkonsultasilah dengan pakar keamanan . Ini adalah masalah serius yang menyakitkan dan mudah salah.
Sangat penting bahwa tidak ada skrip lain yang memiliki akses ke halaman. Ini berarti Anda hanya mengizinkan skrip eksternal dengan pekerja web. Anda tidak dapat mempercayai skrip eksternal lain yang mungkin memotong kata sandi Anda saat pengguna memasukkannya.
Gunakan bidang
prompt
dan bukan bidang kata sandi sebaris jika Anda tidak sepenuhnya yakin dan tidak menunda pelaksanaannya (artinya, itu tidak boleh langsung sampai pada titik di mana acara memiliki akses ke sana tetapi hanya dalam kode sinkronisasi). Dan jangan benar-benar menyimpan kata sandi dalam variabel - sekali lagi, ini hanya berfungsi jika Anda percaya komputer pengguna tidak terganggu (meskipun itu semua berlaku untuk memvalidasi terhadap server juga).Saya ingin menambahkan lagi bahwa kami masih tidak mempercayai klien . Anda tidak bisa mempercayai klien sendirian, dan saya pikir jawaban Joachim berhasil. Kami hanya memperoleh kemudahan karena tidak perlu melakukan ping server sebelum mulai bekerja.
Bahan terkait:
sumber
window.prompt
metode untuk mencegat frase pass, atau meluncurkan prompt sendiri (mungkin dalam iframe!). Bidang kata sandi memiliki satu manfaat tambahan: karakter tidak ditampilkan.Sederhana: mekanisme keamanan apa pun yang bergantung pada klien untuk melakukan apa yang Anda suruh dapat dikompromikan ketika penyerang memiliki kendali atas klien.
Anda dapat memiliki pemeriksaan keamanan pada klien, tetapi hanya untuk secara efektif bertindak sebagai "cache" (untuk menghindari melakukan perjalanan pulang pergi yang mahal ke server jika klien sudah tahu bahwa jawabannya akan "tidak").
Jika Anda ingin menyimpan informasi dari sekelompok pengguna, pastikan bahwa klien pengguna itu tidak pernah mendapatkan informasi itu. Jika Anda mengirim "data rahasia" itu bersama dengan instruksi "tapi tolong jangan tampilkan," itu akan menjadi sepele untuk menonaktifkan kode yang memeriksa permintaan itu.
Seperti yang Anda lihat, jawaban ini tidak benar-benar menyebutkan spesifik JavaScript / Browser. Itu karena konsep ini sama, tidak peduli apa pun klien Anda. Tidak masalah apakah itu klien yang gemuk (aplikasi klien / server tradisional), aplikasi web sekolah lama, atau aplikasi satu halaman dengan JavaScript sisi klien yang luas.
Setelah data Anda meninggalkan server, Anda harus mengasumsikan bahwa penyerang memiliki akses penuh ke sana.
sumber
Ada pepatah di komunitas game: " Klien ada di tangan musuh". Kode apa pun yang berjalan di luar area aman seperti server rentan. Dalam skenario paling dasar, rentan untuk tidak dijalankan di tempat pertama. Keputusan klien untuk benar-benar menjalankan" kode keamanan "Anda dan pengguna dapat hanya "memilih keluar". Sementara dengan kode asli Anda memiliki setidaknya kebingungan otomatis ke dalam perakitan dan lapisan perlindungan tambahan oleh fakta bahwa penyerang harus menjadi programmer yang baik untuk memanipulasi itu, JS biasanya tidak terganggu dan sebagai teks biasa. Yang Anda butuhkan untuk melakukan serangan adalah alat primitif seperti server proxy dan editor teks. Penyerang masih membutuhkan tingkat pendidikan tertentu mengenai pemrograman, tetapi cara memodifikasi script menggunakan texteditor lebih mudah daripada memasukkan kode ke dalam executable.
sumber
Ini bukan pertanyaan tentang peretasan JavaScript. Jika saya ingin menyerang aplikasi Anda, saya akan menggunakan proxy pribadi yang memungkinkan saya untuk menangkap, memodifikasi, dan memutar ulang lalu lintas. Skema keamanan yang Anda usulkan tampaknya tidak memiliki perlindungan terhadap hal itu.
sumber
Secara khusus berbicara tentang Angular:
Melindungi sisi klien rute tidak ada. Sekalipun Anda 'menyembunyikan' tombol untuk rute itu, pengguna selalu dapat mengetiknya, Angular akan mengeluh, tetapi klien dapat mengkodekannya.
Pada titik tertentu pengontrol Anda harus meminta server Anda data yang diperlukan untuk membuat tampilan, jika pengguna tidak berwenang untuk mengakses data itu, mereka tidak akan menerimanya karena Anda telah melindungi data ini di sisi server , dan aplikasi Angular Anda harus menangani 401 dengan tepat.
Jika Anda mencoba melindungi data mentah, Anda tidak dapat sisi klien, jika Anda hanya ingin pengguna tertentu hanya dapat melihat data umum dengan cara tertentu, buat data 'tampilan' pada server daripada mengirim mentah data ke klien dan memilikinya mengatur ulang (Anda harus sudah melakukan ini karena alasan kinerja).
Catatan: seharusnya tidak ada sesuatu yang sensitif yang dibangun ke tampilan templat yang diminta Angular, tapi jangan lakukan itu. Jika karena alasan gila, Anda perlu melindungi template tampilan tersebut di sisi server, sama seperti yang Anda lakukan jika Anda melakukan rendering sisi server.
sumber