it-swarm-id.com

Bagaimana Menerapkan Fitur "Remember Me" dengan Aman?

Dengan asumsi Anda sudah memiliki situs web yang mengimplementasikan semua hal-hal login standar, apa cara yang benar dan paling aman untuk memungkinkan pengguna masuk secara otomatis untuk periode waktu tertentu (misalkan 30 hari)? Periode waktu ini harus ditegakkan secara ketat; yaitu, saya tidak berpikir solusi yang valid akan memberikan cookie tanggal kedaluwarsa dan berharap browser pengguna menghapusnya tepat waktu.

Detail sistem login yang ada:

  • Pengguna harus memasukkan nama pengguna dan kata sandi
  • Basis data menyimpan nama pengguna dan juga strong_hash_fungsi (kata sandi + user_specific_random_salt)
  • Formulir login dimuat dan dikirimkan melalui SSL, seperti semua halaman berikutnya

Ada banyak contoh di luar sana dan banyak dengan kelemahan keamanan yang jelas. Mari kita gunakan PHP sebagai bahasa target tetapi konsep harus berlaku untuk bahasa apa pun.

57
colithium

Jawaban saya tidak lengkap dan memiliki cacat nontrivial, dalam beberapa situasi - silakan lihat @ Scott menjawab sebagai gantinya.


Ada dua bagian jawaban saya:

Pertama, dengan asumsi model ancaman Anda tidak khawatir tentang eksposur cookie sisi klien , Anda dapat membuat dan menyimpan nonce di sisi server, hash itu dengan nama pengguna dan info lainnya (mis. ip klien, nama pengguna, stempel waktu, hal-hal serupa), dan kirimkan dalam cookie. Nonce harus disimpan dalam database, bersama dengan tanggal kadaluwarsa, dan keduanya diperiksa ketika cookie kembali.
Ini harus hanya cookie "pengingat", BUKAN cookie sesi - yaitu ketika Anda mendapatkan cookie itu tanpa sesi, diterbitkan ulang cookie sesi reguler yang baru. Juga perhatikan bahwa seperti cookie sesi, ini harus dikirimkan hanya melalui https, dan menggunakan atribut secure dan httpOnly, dan tentu saja cookie dilingkupi dengan benar dll.

Kedua, untuk pengguna yang diingat, Anda harus (mungkin, tergantung pada sensitivitas) meminta proses reauthentikasi untuk operasi sensitif tertentu. Artinya, kadang-kadang mereka perlu memasukkan kata sandi mereka lagi, tetapi jarang, dan hanya untuk operasi yang sensitif. Ini untuk mencegah serangan seperti CSRF dan paparan desktop bersama.

31
AviD

Saya telah menulis panjang lebar tentang login aman dan kotak centang "ingat saya" . Jawaban yang diterima tidak salah, tapi saya berpendapat bahwa itu sedikit lebih rumit dalam satu hal daripada yang seharusnya, dan mengabaikan area di mana sedikit lebih banyak kompleksitas diperlukan.

menghasilkan dan menyimpan nilai di sisi server, hash dengan nama pengguna dan info lainnya (mis. ip klien, nama pengguna, stempel waktu, hal-hal serupa), dan kirimkan dalam cookie. Nonce harus disimpan dalam database, bersama dengan tanggal kadaluwarsa, dan keduanya diperiksa ketika cookie kembali.

Jadi implementasi yang tidak memaparkan informasi apa pun kepada klien mungkin terlihat seperti ...

// Storage:
setcookie(
    'rememberme',
    hash_hmac('sha256', $username . $_SERVER['REMOTE_ADDR'], $storedNonce),
    time() + 8640000 // 100 days, for example
);
// Validation:
$valid = hash_equals(
    $_COOKIE['rememberme'],
    hash_hmac('sha256', $username . $_SERVER['REMOTE_ADDR'], $storedNonce)
);

Batasan yang jelas di sini adalah bahwa, jika alamat IP Anda (atau informasi lainnya) berubah, cookie Anda tidak berguna. Beberapa mungkin melihat ini sebagai hal yang baik, saya melihatnya sebagai permusuhan yang tidak perlu terhadap pengguna Tor.

Anda tentu dapat mengartikan kutipan di atas untuk mengartikan sesuatu yang berbeda, seperti token JSON Web orang miskin, juga. Namun, cookie HTTP dibatasi hingga 4 KiB per domain. Ruang di premium.

Masalah lain: Berapa banyak informasi yang bocor dari permintaan basis data tentang aplikasi Anda? (Ya, saya sedang berbicara tentang saluran samping.)


Strategi Aman "Ingat Aku" dari Paragon Initiative

Penyimpanan:

  1. Hasilkan string 9 byte acak dari random_bytes() (PHP 7.0+ atau via random_compat ), base64 menyandikannya menjadi 12. Ini akan digunakan untuk pencarian basis data.
  2. Hasilkan string acak lain, lebih disukai setidaknya 18 byte, dan sekali lagi base64 mengkodekannya (menjadi 24+). Ini sebenarnya akan digunakan untuk otentikasi.
  3. Simpan $lookup Dan hash('sha256, $validator) dalam database; tentu saja terkait dengan akun pengguna tertentu.
  4. Simpan $lookup . $validator Di cookie HTTP pengguna (mis. rememberme).

Validasi (Login Otomatis):

  1. Bagi cookie menjadi $lookup Dan $validator.
  2. Lakukan pencarian basis data berdasarkan $lookup; tidak apa-apa jika ada saluran samping waktu di sini.
  3. Periksa hash_equals($row['hashedValdator'], hash('sha256', $validator)).
  4. Jika langkah 3 mengembalikan TRUE, kaitkan sesi saat ini dengan akun pengguna yang sesuai.

Analisis Keamanan:

  • Saluran samping apa yang dimitigasi?
    Paling signifikan: ini mengurangi dampak kebocoran informasi waktu pada operasi perbandingan string yang digunakan dalam pencarian basis data.

    Jika Anda menerapkan otentikasi token acak naif, penyerang dapat mengirim banyak permintaan hingga mereka menemukan token otentikasi yang valid untuk pengguna. (Mereka mungkin tidak akan bisa memilih korban yang mereka tiru.)

  • Bagaimana jika penyerang dapat membocorkan tabel database otentikasi jangka panjang?
    Kami menyimpan hash SHA256 dari $validator Dalam database, tetapi plaintext untuk hash disimpan dalam cookie. Karena input adalah nilai entropi tinggi, pencarian brute force tidak mungkin menghasilkan hasil apa pun. (Ini juga mengurangi kebutuhan untuk mis. Bcrypt.)

Strategi ini diterapkan di Gatekeeper .

10

Itu pertanyaan yang menarik. Saya akan memulai dengan mengatakan bahwa saya tidak yakin itu bisa dilakukan tanpa sedikit pelemahan keamanan aplikasi, tetapi kemudian tergantung pada situs yang mungkin dianggap layak untuk ditukar.

Jadi satu pendekatan bisa jadi

Basis data keadaan sesi harus mencatat waktu yang ditetapkan token dan durasi yang harus diingat sehingga dapat membandingkan token yang disajikan.

Ketika pengguna masuk ke aplikasi mereka memiliki kotak centang yang memungkinkan mereka tetap masuk (idealnya dengan rentang periode waktu untuk dipilih oleh pengguna)

Ketika token sesi diatur, periode waktu itu digunakan sebagai cookie berakhir. Pada kunjungan berikutnya, cookie akan disajikan ke aplikasi, dan server harus memeriksa apakah masih valid (yaitu periode kedaluwarsa untuk fungsi ingat saya belum dipukul). Jika token masih valid, pengguna diperlakukan sebagai dikonfirmasi, jika tidak maka token dihapus dan pengguna diarahkan ke layar login.

Masalah dengan pendekatan ini. Browser bersama akan berarti bahwa akses yang tidak sah dimungkinkan.

Juga siapa pun yang bisa mendapatkan akses ke cookie (baik melalui kerentanan di situs, masalah browser atau melalui malware yang ditanam di mesin) akan bisa mendapatkan akses tidak sah ke situs. Satu saran umum untuk mengurangi ini adalah mencoba untuk mengikat cookie ke alamat IP sumber (dienkripsi atau disimpan di server tentu saja) yang diperiksa ketika pengguna menyajikan cookie, namun ini menyebabkan masalah dengan lingkungan perusahaan besar di mana pengguna dapat datang dari sejumlah alamat IP, dan juga mungkin rentan terhadap spoofing.

5
Rory McCune

Anda tidak harus bergantung pada browser untuk menghapus cookie, Anda memiliki situs memeriksa tanggal kedaluwarsa pada cookie.

Bahkan, agar ini aman, saya katakan itu mungkin yang harus Anda lakukan, karena Anda ingin menetapkan tanggal kedaluwarsa sebagai bagian dari nilai cookie dan mengenkripsi itu daripada mengandalkan properti kedaluwarsa teks biasa dari cookie itu sendiri.

Dan Anda benar-benar ingin menandai cookie sebagai aman, dan menggunakan cookie sekunder selama durasi sesi individual, atau melindungi seluruh sesi (bukan hanya proses login) dengan SSL untuk mencegah cookie dicuri dari kawat. dan digunakan oleh pihak yang tidak berwenang.

4
Xander

Artikel ini menjelaskan pendekatan yang melindungi terhadap pencurian cookie dan menebak ID sesi:

  • Cookie "ingat saya" terdiri dari ID pengguna, token (nomor acak besar) dan token urutan (nomor acak besar lainnya).
  • Ketika seorang pengguna menyajikan cookie, basis data dicari untuk ketiga informasi ini.
    • Jika ditemukan, token urutan dibuat ulang, disimpan dalam database dan dikirim ke pengguna
    • Jika hanya nama pengguna dan token yang ditemukan, diduga orang lain telah mencuri cookie karena token urutan sudah digunakan. Sistem kemudian dapat memperingatkan pengguna dan/atau menghapus semua token yang tersimpan dari pengguna ini dari database.

Sebagai tindakan pengamanan tambahan, disarankan tindakan kritis seperti mengubah data login atau membayar barang meminta kata sandi, jika pengguna hanya diautentikasi dengan cookie "ingat saya".

Tabel database yang berisi id dan token pengguna juga berisi tanggal kedaluwarsa token. Bisa juga berisi agen pengguna dan alamat IP sehingga penyerang harus mereplikasi ini juga. Semua token hanya boleh disimpan sebagai hash karena mereka pada dasarnya berfungsi seperti kata sandi dan akan memungkinkan penyerang, yang memperoleh basis data, untuk login.

Saya telah membuat contoh implementasi untuk PHP.

0
chiborg