it-swarm-id.com

Mengamankan Aplikasi Satu Halaman JavaScript dengan backend TENANG

Saat ini saya sedang dalam proses membangun SPA JavaScript dan telah meneliti cara mengamankannya. Saat ini ada RESTful API yang sedang sepenuhnya berinteraksi dengan melalui AJAX. Kami juga memiliki klien seluler yang berinteraksi dengan API ini, dan saat ini hanya mendukung HTTP BASIC Authentication melalui SSL. Aplikasi JavaScript juga akan berkomunikasi secara eksklusif melalui SSL, tetapi BASIC Auth tidak akan memotongnya karena itu akan melibatkan penyimpanan kata sandi (atau turunannya) pada klien. Terakhir, aplikasi SPA akan menjadi murni JavaScript dan HTML, disajikan di server yang sama dengan RESTful API, tetapi tanpa kerangka sisi server.

Sasaran :

  • Tidak ada kerangka kerja sisi server untuk klien javascript (ini hanyalah klien lain).
  • Pertahankan statelessness dari RESTful API, untuk alasan-alasan umum (skalabilitas, toleransi kesalahan, penyebaran yang disederhanakan, dll)
  • Status apa pun harus dipertahankan oleh klien. Untuk keperluan pertanyaan ini, ini berarti kredensial masuk.
  • Keadaan login yang dikelola oleh klien harus aman dan tahan terhadap pembajakan sesi dan serangan serupa.

Apa yang saya hasilkan didasarkan pada penelitian saya tentang OAuth dan skema serupa (Amazon, dll).

  1. Pengguna akan login menggunakan dan HTTP POST melalui SSL.
  2. Server akan menghitung hash sebagai berikut:

    HMAC (kunci, userId + ":" + ipAddress + ":" + userAgent + ":" + todaysDateInMilliseconds)

  3. Token ini akan dikembalikan ke klien dan diberikan setiap permintaan berikutnya sebagai ganti nama pengguna dan kata sandi. Kemungkinan besar akan disimpan di Penyimpanan lokal atau cookie.

Apakah ini aman? Motivasi saya untuk memilih userId, ipAddress, todaysDateInMilleseconds adalah membuat token yang hanya berlaku hari ini, tetapi tidak memerlukan pencarian basis data untuk setiap permintaan DAN aman untuk disimpan pada klien. Saya tidak dapat mempercayai bahwa kuncinya tidak akan dikompromikan, dengan demikian dimasukkannya Alamat IP dalam upaya untuk mencegah pembajakan sesi.

Izinkan saya menyertakan tautan berikut dari pos terkait di StackExchange karena saya pikir ini membahas banyak masalah yang saya coba selesaikan: REST and Stateless Session Id

Setelah umpan balik awal di sini, saya memutuskan untuk hanya menggunakan dua oktaf pertama dari alamat IP untuk menangani klien di belakang proxy dan klien seluler dengan lebih baik. Ini masih belum sempurna, tetapi merupakan tradeoff untuk beberapa keamanan tambahan.

68
Jon Wingfield

Layanan yang ditawarkan oleh token adalah server entah bagaimana akan mengenali token sebagai salah satu tokennya sendiri. Bagaimana server dapat memvalidasi token berbasis HMAC? Dengan mengkomputasi ulang, menggunakan kunci rahasia HAMC dan data di mana HMAC beroperasi . Jika Anda ingin token Anda dihitung menggunakan ID pengguna, kata sandi, IP dan tanggal, maka server harus mengetahui semua informasi itu. Namun, Anda tidak ingin server Anda menyimpan kata sandi, dan klien tidak akan mengirimnya kembali dengan setiap permintaan. Bagaimana cara kerja sistem Anda?

Namun, ide dasarnya adalah:

  • Pengguna "masuk" dengan cara apa pun yang Anda inginkan.
  • Setelah login tersebut, server mengirimkan nilai cookie, untuk dikirim kembali dengan setiap permintaan berikutnya (itulah yang dilakukan cookie).
  • Cookie tersebut berisi ID pengguna, tanggal dikeluarkannya, dan nilai m = HMAC (K, userID || date || IP) .
  • Ketika server menerima permintaan, itu memvalidasi cookie: userID dan tanggal berasal dari cookie itu sendiri, IP sumber diperoleh dari lapisan server Web, dan server dapat menghitung ulang nilai m untuk memeriksa apakah cocok dengan yang disimpan dalam cookie.

Anda bisa mengganti seluruh cookie dengan ID sesi acak, jika server memiliki beberapa ruang penyimpanan (sementara). Memang, server dapat mengingat pemetaan dari ID sesi acak ke informasi spesifik pengguna (seperti nama dan alamat IP); ID sesi lama dapat secara otomatis kedaluwarsa, sehingga ruang penyimpanan tidak bertambah tanpa batas. Cookie yang dijelaskan di atas hanyalah cara untuk membongkar penyimpanan pada klien itu sendiri.

Catatan: menggunakan alamat IP dapat menyiratkan beberapa masalah praktis. Beberapa klien berada di belakang proxy, bahkan proxy load-seimbang, jadi bukan hanya alamat IP klien mungkin "disembunyikan" (dari server, Anda melihat alamat proxy, bukan alamat klien) tetapi alamat IP yang Anda dapatkan dari sisi server bisa bergerak secara tidak menentu (jika dua permintaan berturut-turut dari klien telah melalui proxy yang berbeda di proxy farm).

30
Thomas Pornin

Ada solusi yang lebih sederhana:

Gunakan SSL sitewide, dan kemudian gunakan pelacakan sesi standar kerangka kerja Anda.

Itu semua yang perlu Anda lakukan.

Secara lebih rinci, pengguna awalnya masuk dengan memberikan nama pengguna dan kata sandi mereka; itu akan dikirim ke server, yang dapat memeriksa validitasnya. Jika otentikasi berhasil, kode server Anda menetapkan bendera di status sesi mengingat bahwa pengguna telah berhasil mengautentikasi dan mengingat nama pengguna pengguna. Semua permintaan berikutnya akan melalui sesi yang sama, sehingga Anda dapat dengan mudah mengotentikasi dan mengizinkannya untuk melanjutkan.

(Masih lebih detail: Setiap kali Anda menerima permintaan, Anda memeriksa status sesi untuk melihat apakah pengguna telah berhasil mengautentikasi dan berwenang untuk melakukan tindakan ini. Jika ya, Anda mengizinkan permintaan dan melakukan tindakan; jika tidak, Anda mengarahkan ulang pengguna ke halaman login atau menyajikan beberapa pesan kesalahan lainnya.)

Perhatikan bahwa ini memenuhi semua persyaratan Anda. Tidak memerlukan pencarian basis data pada setiap permintaan. Ini kompatibel dengan API yang tenang. Ini kompatibel dengan aplikasi satu halaman. Anda tidak perlu membuat kode apa pun yang mewah: Anda hanya menggunakan dukungan kerangka kerja yang ada untuk sesi (biasanya, menggunakan cookie sesi dengan ID sesi unik, dan beberapa mekanisme untuk menyimpan keadaan di sisi server yang terkait dengan ID sesi itu) .

Sebagai bagian dari penggunaan SSL sitewide, Anda harus mengatur flag secure pada cookie ID sesi Anda, untuk melindunginya dari menguping (ini akan memastikan tidak akan pernah dikirim melalui HTTP). Anda juga harus mengaktifkan HSTS, untuk memberi tahu browser untuk selalu menggunakan SSL di situs Anda. Cari situs ini untuk informasi lebih lanjut tentang cara menggunakan SSL seluruh situs.

Anda tidak boleh mengandalkan alamat IP klien untuk menjadi statis. Mungkin berubah, mis., Jika klien seluler dan berpindah dari satu jaringan nirkabel ke yang lain. Oleh karena itu, yang terbaik adalah menghindari menggunakan alamat IP klien untuk apa pun.

9
D.W.

Periksa pos ini Menggunakan OAuth2 di Aplikasi Web HTML5 . @jandersen jawaban memberikan penjelasan yang baik tentang penggunaan kredensial kata sandi pemilik sumber daya mengalir dalam aplikasi halaman tunggal. Bagaimanapun, aliran yang disukai untuk aplikasi ini harus --- Hibah implisit . Bahkan, tanggapan @jandersen pada posting yang dirujuk adalah tentang mengutak-atik kredensial kata sandi pemilik Sumber Daya untuk bertindak sebagai sesuatu yang dekat dengan hibah Tersirat.

3
Daniel Cerecedo