Pertanyaan Panduan definitif untuk membentuk otentikasi situs web berbasis [tertutup]


Otentikasi berbasis formulir untuk situs web

Kami percaya bahwa Stack Overflow tidak boleh hanya menjadi sumber daya untuk pertanyaan teknis yang sangat spesifik, tetapi juga untuk panduan umum tentang cara menyelesaikan variasi pada masalah umum. "Otentikasi berbasis formulir untuk situs web" seharusnya menjadi topik yang bagus untuk eksperimen semacam itu.

Ini harus mencakup topik-topik seperti:

  • Bagaimana cara masuk
  • Bagaimana cara keluar
  • Cara tetap masuk
  • Mengelola cookie (termasuk pengaturan yang disarankan)
  • Enkripsi SSL / HTTPS
  • Cara menyimpan kata sandi
  • Menggunakan pertanyaan rahasia
  • Lupa fungsi nama pengguna / kata sandi
  • Penggunaan nonces untuk mencegah pemalsuan permintaan lintas situs (CSRF)
  • OpenID
  • Kotak "Ingat saya"
  • Pelengkapan otomatis nama pengguna dan kata sandi browser
  • URL rahasia (publik URL dilindungi oleh intisari)
  • Memeriksa kekuatan kata sandi
  • Validasi email
  • dan masih banyak lagi  otentikasi berbasis form...

Itu tidak termasuk hal-hal seperti:

  • Peran dan otorisasi
  • Otentikasi dasar HTTP

Tolong bantu kami dengan:

  1. Menyarankan subtopik
  2. Mengirimkan artikel bagus tentang subjek ini
  3. Mengedit jawaban resmi

4992


asal


Jawaban:


BAGIAN I: Cara Masuk

Kami akan menganggap Anda sudah tahu cara membuat formulir HTML sandi + masuk yang mem-POST nilai ke skrip di sisi server untuk autentikasi. Bagian di bawah ini akan berurusan dengan pola untuk auth praktis suara, dan bagaimana menghindari jebakan keamanan yang paling umum.

Ke HTTPS atau tidak ke HTTPS?

Kecuali koneksi sudah aman (yaitu, tunneled melalui HTTPS menggunakan SSL / TLS), nilai-nilai form login Anda akan dikirim dalam cleartext, yang memungkinkan siapa pun menguping pada garis antara browser dan server web akan dapat membaca login saat mereka melewati melalui. Jenis penyadapan ini dilakukan secara rutin oleh pemerintah, tetapi secara umum kami tidak akan membahas kabel 'milik' selain untuk mengatakan ini: Jika Anda melindungi sesuatu yang penting, gunakan HTTPS.

Intinya, satu-satunya praktis cara untuk melindungi terhadap penyadapan / paket mengendus selama login adalah dengan menggunakan HTTPS atau skema enkripsi berbasis sertifikat lain (misalnya, TLS) atau skema respons-respons yang terbukti & teruji (misalnya, Diffie-Hellmanberbasis SRP). Metode lain dapat dengan mudah dielakkan oleh penyerang yang menguping.

Tentu saja, jika Anda ingin sedikit tidak praktis, Anda juga bisa menggunakan beberapa bentuk skema autentikasi dua faktor (misalnya aplikasi Google Authenticator, buku gaya 'gaya perang dingin' fisik, atau dongle generator kunci RSA). Jika diterapkan dengan benar, ini dapat bekerja bahkan dengan koneksi yang tidak aman, tetapi sulit untuk membayangkan bahwa dev akan bersedia menerapkan autentikasi dua faktor tetapi tidak SSL.

(Jangan) Roll-sendiri JavaScript enkripsi / hashing

Mengingat biaya non-nol dan kesulitan teknis yang dirasakan dalam menyiapkan sertifikat SSL di situs web Anda, beberapa pengembang tergoda untuk menggulirkan skema hashing atau enkripsi in-browser mereka untuk menghindari melewatkan proses masuk cleartext melalui kabel tanpa jaminan.

Meskipun ini adalah pemikiran yang mulia, pada dasarnya tidak berguna (dan bisa menjadi a celah keamanan) kecuali jika digabungkan dengan salah satu di atas - yaitu, mengamankan baris dengan enkripsi yang kuat atau menggunakan mekanisme respon tantangan yang sudah teruji (jika Anda tidak tahu apa itu, ketahuilah bahwa itu adalah salah satu yang paling sulit dibuktikan, paling sulit untuk dirancang, dan yang paling sulit untuk menerapkan konsep dalam keamanan digital).

Memang benar bahwa hashing password dapat efektif melawan pengungkapan kata sandi, rentan terhadap serangan replay, serangan Man-In-The-Middle / pembajakan (jika penyerang dapat menyuntikkan beberapa byte ke halaman HTML tanpa jaminan Anda sebelum mencapai browser Anda, mereka dapat dengan mudah mengomentari hashing dalam JavaScript), atau serangan brute-force (karena Anda menyerahkan penyerang baik username, salt dan hashed password).

CAPTCHAS melawan kemanusiaan

CAPTCHA dimaksudkan untuk menggagalkan satu kategori serangan spesifik: kamus otomatis / percobaan kasar-dan-kesalahan tanpa operator manusia. Tidak ada keraguan bahwa ini adalah ancaman nyata, namun ada cara untuk menghadapinya dengan mulus yang tidak memerlukan CAPTCHA, secara khusus dirancang dengan baik skema login server - kita akan membahasnya nanti.

Ketahuilah bahwa implementasi CAPTCHA tidak dibuat sama; mereka sering tidak dapat dipecahkan manusia, kebanyakan dari mereka sebenarnya tidak efektif melawan bot, semuanya tidak efektif melawan tenaga kerja dunia ketiga yang murah (menurut OWASP, tingkat sweatshop saat ini adalah $ 12 per 500 tes), dan beberapa penerapan mungkin secara teknis ilegal di beberapa negara (lihat Lembar Cheat Otentikasi OWASP). Jika Anda harus menggunakan CAPTCHA, gunakan Google reCAPTCHA, karena ini adalah OCR-hard by definition (karena menggunakan OCR-misclassified book scan) dan berusaha sangat keras untuk menjadi user-friendly.

Secara pribadi, saya cenderung menganggap CAPTCHAS menjengkelkan, dan menggunakannya hanya sebagai upaya terakhir ketika seorang pengguna gagal login beberapa kali dan penundaan yang melelahkan sudah di-maxx. Ini akan terjadi cukup jarang untuk dapat diterima, dan itu memperkuat sistem secara keseluruhan.

Menyimpan Sandi / Memverifikasi proses masuk

Ini mungkin akhirnya menjadi pengetahuan umum setelah semua peretasan dan kebocoran data pengguna yang dipublikasikan besar-besaran yang telah kita lihat dalam beberapa tahun terakhir, tetapi harus dikatakan: Jangan simpan kata sandi dalam teks-jelas dalam database Anda. Database pengguna diretas secara rutin, bocor atau dikumpulkan melalui injeksi SQL, dan jika Anda menyimpan kata sandi mentah, plaintext, itu adalah permainan instan untuk keamanan login Anda.

Jadi jika Anda tidak dapat menyimpan kata sandi, bagaimana Anda memeriksa bahwa kombinasi login + kata sandi yang dikirim dari formulir login sudah benar? Jawabannya adalah hashing menggunakan fungsi derivasi utama. Setiap kali pengguna baru dibuat atau kata sandi diubah, Anda mengambil kata sandi dan menjalankannya melalui KDF, seperti Argon2, bcrypt, scrypt atau PBKDF2, mengubah kata sandi cleartext ("correcthorsebatterystaple") menjadi string panjang, acak-cari , yang jauh lebih aman untuk disimpan di database Anda. Untuk memverifikasi proses masuk, Anda menjalankan fungsi hash yang sama pada kata sandi yang dimasukkan, kali ini meneruskan garam dan membandingkan string hash yang dihasilkan dengan nilai yang disimpan dalam database Anda. Argon2, bcrypt dan scrypt menyimpan garam dengan hash. Lihat ini artikel di sec.stackexchange untuk informasi lebih detail.

Alasan mengapa garam digunakan adalah karena hashing itu sendiri tidak cukup - Anda akan ingin menambahkan apa yang disebut 'garam' untuk melindungi hash terhadap tabel pelangi. Garam secara efektif mencegah dua kata sandi yang sama persis dari disimpan sebagai nilai hash yang sama, mencegah seluruh pangkalan data dipindai dalam satu run jika penyerang mengeksekusi serangan menebak kata sandi.

Hash cryptographic tidak boleh digunakan untuk penyimpanan kata sandi karena kata sandi yang dipilih pengguna tidak cukup kuat (biasanya tidak mengandung cukup entropi) dan serangan menebak kata sandi dapat diselesaikan dalam waktu yang relatif singkat oleh penyerang dengan akses ke hash. Inilah sebabnya mengapa KDF digunakan - ini efektif "peregangan kunci" artinya setiap kata sandi menebak penyerang membuat melibatkan iterasi algoritma hashing beberapa kali, misalnya 10.000 kali, membuat kata sandi penyerang menebak 10.000 kali lebih lambat.

Data sesi - "Anda masuk sebagai Spiderman69"

Setelah server memverifikasi login dan kata sandi terhadap basis data pengguna Anda dan menemukan kecocokan, sistem memerlukan cara untuk mengingat bahwa peramban telah diautentikasi. Fakta ini seharusnya hanya disimpan di sisi server dalam data sesi.

Jika Anda tidak terbiasa dengan data sesi, begini cara kerjanya: Satu string yang dihasilkan secara acak disimpan dalam cookie yang berakhir dan digunakan untuk referensi kumpulan data - data sesi - yang disimpan di server. Jika Anda menggunakan kerangka kerja MVC, ini tidak diragukan lagi sudah ditangani.

Jika memungkinkan, pastikan cookie sesi memiliki flag Aman dan Hanya HTTP yang disetel ketika dikirim ke browser. Bendera httponly memberikan perlindungan terhadap cookie yang dibaca oleh serangan XSS. Bendera aman memastikan bahwa cookie hanya dikirim kembali melalui HTTPS, dan karena itu melindungi terhadap serangan mengendus jaringan. Nilai cookie seharusnya tidak dapat diprediksi. Jika cookie yang merujuk sesi tidak ada disajikan, nilainya harus segera diganti untuk mencegah fiksasi sesi.

BAGIAN II: Cara Tetap Masuk - Kotak centang "Ingatkan Saya"

Cookie Login Persisten (fungsi "ingat saya") adalah zona bahaya; di satu sisi, mereka sepenuhnya seaman login konvensional ketika pengguna memahami cara menanganinya; dan di sisi lain, mereka adalah risiko keamanan yang sangat besar di tangan pengguna yang ceroboh, yang mungkin menggunakannya di komputer publik dan lupa untuk keluar, dan yang mungkin tidak tahu apa cookie browser atau bagaimana cara menghapusnya.

Secara pribadi, saya suka terus-menerus login untuk situs web yang saya kunjungi secara rutin, tetapi saya tahu cara menanganinya dengan aman. Jika Anda yakin bahwa pengguna Anda mengetahui hal yang sama, Anda dapat menggunakan proses masuk persisten dengan hati nurani yang bersih. Jika tidak - yah, maka Anda dapat berlangganan filosofi bahwa pengguna yang ceroboh dengan kredensial masuk mereka membawanya sendiri jika mereka diretas. Ini tidak seperti kita pergi ke rumah-rumah pengguna kita dan merobek semua catatan Post-It yang memampatkan facepalm dengan kata sandi yang telah mereka antre di tepi monitor mereka juga.

Tentu saja, beberapa sistem tidak mampu memilikinya apa saja akun diretas; untuk sistem seperti itu, tidak ada cara Anda dapat membenarkan memiliki proses masuk persisten.

Jika Anda memutuskan untuk menerapkan cookie login persisten, ini adalah bagaimana Anda melakukannya:

  1. Pertama, luangkan waktu untuk membaca Artikel Paragon Initiative tentang masalah ini. Anda harus mendapatkan banyak elemen dengan benar, dan artikel tersebut sangat bagus untuk menjelaskannya.

  2. Dan hanya untuk mengulangi salah satu perangkap paling umum, JANGAN MENYIMPAN MASUK COOKIE YANG MENGERTI (TOKEN) DI DATABASE ANDA, HANYA BANYAK ITU! Token login adalah Kata Sandi Setara, jadi jika penyerang mendapatkan tangan mereka di basis data Anda, mereka dapat menggunakan token untuk masuk ke akun mana pun, seolah-olah mereka adalah kombinasi kata sandi-masuk cleartext. Oleh karena itu, gunakan hashing (menurut https://security.stackexchange.com/a/63438/5002 hash yang lemah akan baik-baik saja untuk tujuan ini) saat menyimpan token login yang persisten.

BAGIAN III: Menggunakan Pertanyaan Rahasia

Jangan terapkan 'pertanyaan rahasia'. Fitur 'pertanyaan rahasia' adalah anti-pola keamanan. Baca kertas dari tautan nomor 4 dari daftar BACA-BACA. Anda bisa bertanya kepada Sarah Palin tentang hal itu, setelah Yahoo! akun email diretas selama kampanye presiden sebelumnya karena jawaban atas pertanyaan keamanannya adalah ... "Wasilla High School"!

Bahkan dengan pertanyaan yang ditentukan pengguna, kemungkinan besar sebagian besar pengguna akan memilih:

  • Pertanyaan rahasia 'standar' seperti nama gadis ibu atau hewan kesayangan

  • Sepotong sederhana hal-hal sepele yang dapat diangkat siapa pun dari blog, profil LinkedIn, atau yang serupa

  • Setiap pertanyaan yang lebih mudah dijawab daripada menebak kata sandinya. Yang, untuk setiap kata sandi yang layak, adalah setiap pertanyaan yang dapat Anda bayangkan

Kesimpulannya, pertanyaan keamanan secara inheren tidak aman dalam hampir semua bentuk dan variasi, dan tidak boleh digunakan dalam skema otentikasi untuk alasan apa pun.

Alasan sebenarnya mengapa pertanyaan keamanan bahkan ada di alam liar adalah bahwa mereka dengan nyaman menghemat biaya dari beberapa panggilan dukungan dari pengguna yang tidak dapat mengakses email mereka untuk mendapatkan kode reaktivasi. Ini dengan mengorbankan keamanan dan reputasi Sarah Palin. Setimpal? Mungkin tidak.

BAGIAN IV: Fungsionalitas Kata Sandi yang Terlupakan

Saya sudah menyebutkan mengapa Anda harus jangan pernah menggunakan pertanyaan keamananuntuk menangani kata sandi pengguna yang terlupakan / hilang; Anda juga tidak perlu mengatakan bahwa Anda tidak boleh mengirimi pengguna e-mail kata sandi yang sebenarnya. Setidaknya ada dua jebakan yang terlalu umum untuk dihindari dalam bidang ini:

  1. Jangan ulang lupa kata sandi untuk kata sandi yang kuat otomatis - kata sandi semacam itu sangat sulit untuk diingat, yang berarti pengguna harus mengubahnya atau menuliskannya - katakanlah, pada Post-It kuning cerah di tepi monitor mereka. Daripada menetapkan kata sandi baru, biarkan pengguna memilih yang baru segera - yang memang ingin mereka lakukan. (Pengecualian untuk ini mungkin jika pengguna secara universal menggunakan pengelola kata sandi untuk menyimpan / mengelola kata sandi yang biasanya tidak mungkin diingat tanpa menuliskannya).

  2. Selalu hash kode sandi / token yang hilang dalam database. LAGI, kode ini adalah contoh lain dari Kata Sandi Setara, jadi itu HARUS di-hash jika seorang penyerang mendapatkan tangan mereka di database Anda. Ketika kode kata sandi yang hilang diminta, kirim kode plaintext ke alamat email pengguna, lalu hash it, simpan hash dalam database Anda - dan buang yang asli. Sama seperti kata sandi atau token login persisten.

Catatan terakhir: selalu pastikan antarmuka Anda untuk memasukkan 'kode sandi yang hilang' setidaknya sama amannya dengan form login Anda sendiri, atau penyerang hanya akan menggunakan ini untuk mendapatkan akses sebagai gantinya. Memastikan Anda menghasilkan 'kode sandi hilang' yang sangat panjang (misalnya, 16 karakter alfanumerik huruf besar) adalah awal yang baik, tetapi pertimbangkan untuk menambahkan skema pelambatan yang sama yang Anda lakukan untuk formulir login itu sendiri.

BAGIAN V: Memeriksa Kekuatan Kata Sandi

Pertama, Anda ingin membaca artikel kecil ini untuk melihat realitas: 500 kata sandi yang paling umum

Oke, jadi mungkin daftar itu bukan resmi daftar kata sandi yang paling umum di apa saja sistem di mana saja, tetapi ini adalah indikasi yang baik tentang bagaimana orang yang buruk akan memilih kata sandi mereka ketika tidak ada kebijakan yang diberlakukan. Ditambah lagi, daftar itu tampak menakutkan di dekat rumah ketika Anda membandingkannya dengan analisis yang tersedia secara publik dari kata sandi yang baru-baru ini dicuri.

Jadi: Tanpa persyaratan kekuatan kata sandi minimum, 2% pengguna menggunakan salah satu dari 20 kata sandi paling umum. Artinya: jika penyerang hanya mendapat 20 percobaan, 1 dari 50 akun di situs web Anda akan dapat di-crack.

Menghalangi ini membutuhkan perhitungan entropi kata sandi dan kemudian menerapkan ambang batas. Lembaga Standar dan Teknologi Nasional (NIST) Publikasi Khusus 800-63 memiliki seperangkat saran yang sangat bagus. Itu, ketika dikombinasikan dengan kamus dan analisis layout keyboard (misalnya, 'qwertyuiop' adalah kata sandi yang buruk), bisa menolak 99% dari semua kata sandi yang dipilih dengan buruk pada tingkat 18 bit entropi. Cukup menghitung kekuatan kata sandi dan menunjukkan kekuatan pengukur visual kepada pengguna adalah baik, tetapi tidak cukup. Kecuali jika diberlakukan, banyak pengguna kemungkinan besar akan mengabaikannya.

Dan untuk mendapatkan kata sandi high-entropy yang ramah pengguna, Randall Munroe Kekuatan Kata Sandi xkcd sangat dianjurkan.

BAGIAN VI: Banyak Lagi - Atau: Mencegah Percobaan Login Cepat-Api

Pertama, lihat angka-angkanya: Kecepatan Pemulihan Kata Sandi - Berapa lama kata sandi Anda akan berdiri

Jika Anda tidak punya waktu untuk melihat-lihat tabel di tautan itu, berikut daftarnya:

  1. Dibutuhkan hampir tidak ada waktu untuk meretas kata sandi yang lemah, bahkan jika Anda memecahkannya dengan sempoa

  2. Dibutuhkan hampir tidak ada waktu untuk meretas kata sandi 9-karakter alfanumerik, jika ya case sensitive

  3. Dibutuhkan hampir tidak ada waktu untuk memecahkan kata kunci yang rumit, simbol-dan-huruf-dan-angka, huruf besar dan huruf kecil, jika ya kurang dari 8 karakter (PC desktop dapat mencari seluruh ruang kunci hingga 7 karakter dalam hitungan hari atau bahkan jam)

  4. Akan, bagaimanapun, mengambil banyak sekali waktu untuk memecahkan bahkan kata sandi 6 karakter, jika Anda terbatas pada satu upaya per detik!

Jadi apa yang bisa kita pelajari dari angka-angka ini? Yah, banyak, tapi kita bisa fokus pada bagian yang paling penting: fakta yang mencegah sejumlah besar upaya login yang cepat-berturut-turut (mis. kasar serangan) benar-benar tidak terlalu sulit. Tapi mencegahnya kanan tidak semudah kelihatannya.

Secara umum, Anda memiliki tiga pilihan yang semuanya efektif terhadap serangan brute-force (dan serangan kamus, tetapi karena Anda sudah menggunakan kebijakan kata sandi yang kuat, seharusnya tidak menjadi masalah):

  • Menyajikan a CAPTCHA setelah upaya N gagal (menjengkelkan sekali dan sering tidak efektif - tetapi saya mengulangi sendiri di sini)

  • Mengunci akun dan membutuhkan verifikasi email setelah upaya N gagal (ini adalah a DoS serangan menunggu untuk terjadi)

  • Dan akhirnya, masuk pelambatan: yaitu, mengatur waktu tunda antara upaya setelah upaya yang gagal N (ya, serangan DoS masih mungkin, tetapi setidaknya mereka jauh lebih mungkin dan jauh lebih rumit untuk melakukan).

Praktik terbaik # 1: Penundaan waktu singkat yang meningkat dengan jumlah upaya yang gagal, seperti:

  • 1 upaya gagal = tidak ada penundaan
  • 2 upaya gagal = delay 2 detik
  • 3 upaya gagal = 4 detik penundaan
  • 4 upaya gagal = 8 detik penundaan
  • 5 kali percobaan gagal = 16 detik
  • dll.

DoS yang menyerang skema ini akan sangat tidak praktis, karena waktu penguncian yang dihasilkan sedikit lebih besar daripada jumlah waktu lockout sebelumnya.

Untuk memperjelas: Penundaan ini tidak penundaan sebelum mengembalikan respons ke browser. Ini lebih seperti batas waktu atau periode refraktori selama upaya login ke akun tertentu atau dari alamat IP tertentu tidak akan diterima atau dievaluasi sama sekali. Artinya, kredensial yang benar tidak akan kembali dalam proses masuk yang berhasil, dan kredensial yang salah tidak akan memicu peningkatan penundaan.

Praktik terbaik # 2: Penundaan waktu panjang menengah yang berlaku setelah upaya N gagal, seperti:

  • 1-4 usaha yang gagal = tidak ada penundaan
  • 5 upaya gagal = 15-30 menit tunda

DoS yang menyerang skema ini akan sangat tidak praktis, tetapi tentu bisa dilakukan. Juga, mungkin relevan untuk dicatat bahwa penundaan yang lama dapat sangat mengganggu bagi pengguna yang sah. Pengguna yang lupa akan tidak menyukai Anda.

Praktik terbaik # 3: Menggabungkan dua pendekatan - baik penundaan waktu tetap, singkat yang berlaku setelah upaya N gagal, seperti:

  • 1-4 usaha yang gagal = tidak ada penundaan
  • 5+ upaya gagal = 20 detik keterlambatan

Atau, penundaan yang meningkat dengan batas atas tetap, seperti:

  • 1 upaya gagal = delay 5 detik
  • 2 kali percobaan gagal = 15 detik
  • 3+ upaya gagal = 45 detik tunda

Skema final ini diambil dari saran-saran praktik terbaik OWASP (tautan 1 dari daftar BACA-BACA), dan harus dianggap praktik terbaik, bahkan jika itu memang diakui di sisi yang terbatas.

Namun, sebagai aturan praktis, saya akan mengatakan: semakin kuat kebijakan kata sandi Anda, semakin sedikit Anda harus bug pengguna dengan penundaan. Jika Anda membutuhkan alfanumerik yang kuat (angka alfanumerik peka + nomor dan simbol yang diperlukan) 9+ sandi karakter, Anda dapat memberi pengguna 2-4 upaya sandi yang tidak tertunda sebelum mengaktifkan pelambatan.

DoS yang menyerang skema login terakhir ini akan menjadi sangat tidak praktis. Dan sebagai sentuhan terakhir, selalu izinkan terus-menerus (cookie) login (dan / atau formulir login yang diverifikasi CAPTCHA) untuk dilewati, sehingga pengguna yang sah tidak akan ditunda sementara serangan sedang berlangsung. Dengan begitu, serangan DoS yang sangat tidak praktis menjadi sangat serangan tidak praktis.

Selain itu, masuk akal untuk melakukan pemblokiran yang lebih agresif pada akun admin, karena itu adalah titik masuk yang paling menarik

BAGIAN VII: Menyebarkan Serangan Brute Force

Persis sebagai penyisihan, penyerang yang lebih maju akan mencoba untuk menghindari masuknya pembatasan dengan 'menyebarkan aktivitas mereka':

  • Mendistribusikan upaya pada botnet untuk mencegah penandaan alamat IP

  • Daripada memilih satu pengguna dan mencoba 50.000 kata sandi yang paling umum (yang mereka tidak bisa, karena pelambatan kami), mereka akan memilih kata sandi yang paling umum dan mencobanya terhadap pengguna 50.000 sebagai gantinya. Dengan cara itu, mereka tidak hanya mendapatkan langkah-langkah upaya maksimal seperti CAPTCHA dan login yang terbatas, peluang keberhasilan mereka juga meningkat, karena password nomor 1 paling umum jauh lebih mungkin daripada nomor 49,995

  • Memberikan jarak pada permintaan login untuk setiap akun pengguna, misalnya, 30 detik terpisah, untuk menyelinap di bawah radar

Di sini, praktik terbaiknya mencatat jumlah login yang gagal, di seluruh sistem, dan menggunakan rata-rata berjalan dari frekuensi login-buruk situs Anda sebagai dasar untuk batas atas yang kemudian Anda terapkan pada semua pengguna.

Terlalu abstrak? Biarkan saya ulangi:

Katakanlah situs Anda memiliki rata-rata 120 login buruk per hari selama 3 bulan terakhir. Menggunakan itu (menjalankan rata-rata), sistem Anda mungkin menetapkan batas global menjadi 3 kali lipat - yaitu. 360 upaya gagal selama periode 24 jam. Kemudian, jika jumlah total upaya gagal di semua akun melebihi jumlah tersebut dalam satu hari (atau bahkan lebih baik, pantau laju percepatan dan pemicu pada ambang batas yang dihitung), ini akan mengaktifkan pelambatan masuk seluruh sistem - artinya penundaan singkat untuk SEMUA pengguna (masih, dengan pengecualian cookie login dan / atau backup login CAPTCHA).

Saya juga mengirim pertanyaan dengan lebih detail dan diskusi yang sangat bagus tentang cara menghindari pitfals yang rumit dalam menangkis serangan brute force yang terdistribusi

BAGIAN VIII: Penyedia Otentikasi dan Autentikasi Dua Faktor

Kredensial dapat dikompromikan, baik oleh eksploit, kata sandi yang ditulis dan hilang, laptop dengan kunci yang dicuri, atau pengguna yang masuk ke situs phishing. Login dapat lebih dilindungi dengan otentikasi dua faktor, yang menggunakan faktor-faktor luar-band seperti kode sekali pakai yang diterima dari panggilan telepon, pesan SMS, aplikasi, atau dongle. Beberapa penyedia menawarkan layanan otentikasi dua faktor.

Autentikasi dapat sepenuhnya didelegasikan ke layanan single-sign-on, di mana penyedia lain menangani pengumpulan kredensial. Ini mendorong masalah ke pihak ketiga tepercaya. Google dan Twitter keduanya menyediakan layanan SSO berbasis standar, sementara Facebook memberikan solusi kepemilikan yang serupa.

LINK MUST-READ Tentang Otentikasi Web

  1. OWASP Guide To Authentication / Lembar Cheat Otentikasi OWASP
  2. Dos dan Don`s of Client Authentication on the Web (makalah penelitian MIT yang sangat mudah dibaca)
  3. Wikipedia: cookie HTTP
  4. Pertanyaan pengetahuan pribadi untuk otentikasi fallback: Pertanyaan keamanan di era Facebook (makalah penelitian Berkeley yang sangat mudah dibaca)

3497



Artikel definitif

Mengirim kredensial

Satu-satunya cara praktis untuk mengirim kredensial 100% secara aman adalah dengan menggunakan SSL. Menggunakan JavaScript untuk hash kata sandi tidak aman. Perangkap umum untuk hashing kata sandi sisi klien:

  • Jika koneksi antara klien dan server tidak terenkripsi, semua yang Anda lakukan adalah rentan terhadap serangan man-in-the-middle. Seorang penyerang dapat mengganti javascript yang masuk untuk memecah hashing atau mengirim semua kredensial ke server mereka, mereka dapat mendengarkan tanggapan klien dan menyamar sebagai pengguna dengan sempurna, dll. SSL dengan Otoritas Sertifikat terpercaya dirancang untuk mencegah serangan MitM.
  • Sandi hash yang diterima oleh server adalah kurang aman jika Anda tidak melakukan pekerjaan tambahan, redundan di server.

Ada metode aman lain yang disebut SRP, tapi itu sudah dipatenkan (meskipun itu berlisensi bebas) dan ada beberapa implementasi bagus yang tersedia.

Menyimpan kata sandi

Jangan pernah menyimpan kata sandi sebagai plaintext dalam database. Bahkan jika Anda tidak peduli dengan keamanan situs Anda sendiri. Asumsikan bahwa beberapa pengguna Anda akan menggunakan kembali kata sandi akun bank online mereka. Jadi, simpan kata sandi yang di-hash, dan buang yang asli. Dan pastikan kata sandi tidak muncul di log akses atau log aplikasi. OWASP merekomendasikan penggunaan Argon2 sebagai pilihan pertama Anda untuk aplikasi baru. Jika ini tidak tersedia, PBKDF2 atau scrypt sebaiknya digunakan. Dan akhirnya jika tidak ada yang tersedia di atas, gunakan bcrypt.

Hash sendiri juga tidak aman. Misalnya, kata sandi identik berarti hash identik - ini membuat tabel pencarian hash menjadi cara yang efektif untuk meretas banyak kata sandi sekaligus. Sebaliknya, simpan asin hash. Garam adalah string yang ditambahkan ke kata sandi sebelum hashing - gunakan garam yang berbeda (acak) per pengguna. Garam adalah nilai publik, sehingga Anda dapat menyimpannya dengan hash dalam database. Lihat sini untuk lebih lanjut tentang ini.

Ini berarti Anda tidak dapat mengirim kata sandi yang terlupakan kepada pengguna (karena Anda hanya memiliki hash). Jangan mereset kata sandi pengguna kecuali Anda telah mengotentikasi pengguna (pengguna harus membuktikan bahwa mereka dapat membaca email yang dikirim ke alamat email yang disimpan (dan divalidasi).)

Pertanyaan keamanan

Pertanyaan keamanan tidak aman - hindari menggunakannya. Mengapa? Apa pun yang dilakukan pertanyaan keamanan, kata sandi berfungsi lebih baik. Baca baca BAGIAN III: Menggunakan Pertanyaan Rahasia di Jawaban @Jens Roland di sini di wiki ini.

Cookie sesi

Setelah pengguna masuk, server mengirim pengguna cookie sesi. Server dapat mengambil nama pengguna atau id dari cookie, tetapi tidak ada orang lain yang dapat menghasilkan cookie semacam itu (TODO menjelaskan mekanisme).

Cookie bisa dibajak: mereka hanya seaman sisa mesin klien dan komunikasi lainnya. Mereka dapat dibaca dari disk, diendus dalam lalu lintas jaringan, diangkat oleh serangan scripting lintas situs, phishing dari DNS yang diracuni sehingga klien mengirimkan cookie mereka ke server yang salah. Jangan kirim cookie yang persisten. Cookie harus kedaluwarsa pada akhir sesi klien (browser tutup atau tinggalkan domain Anda).

Jika Anda ingin autologin pengguna Anda, Anda dapat mengatur cookie tetap, tetapi harus berbeda dari cookie sesi penuh. Anda dapat mengatur bendera tambahan bahwa pengguna telah masuk secara otomatis, dan harus login secara nyata untuk operasi sensitif. Ini populer dengan situs belanja yang ingin memberi Anda pengalaman belanja yang mulus dan pribadi namun tetap melindungi perincian keuangan Anda. Misalnya, ketika Anda kembali mengunjungi Amazon, mereka menunjukkan laman yang terlihat seperti Anda masuk, tetapi ketika Anda pergi untuk melakukan pemesanan (atau mengubah alamat pengiriman, kartu kredit, dll.), Mereka meminta Anda untuk mengonfirmasi kata sandi Anda.

Situs web keuangan seperti bank dan kartu kredit, di sisi lain, hanya memiliki data sensitif dan tidak boleh memungkinkan login otomatis atau mode keamanan rendah.

Daftar sumber daya eksternal


387



Pertama, peringatan kuat bahwa jawaban ini tidak cocok untuk pertanyaan yang tepat ini. Seharusnya tidak menjadi jawaban teratas!

Saya akan melanjutkan dan menyebutkan Mozilla yang diusulkan BrowserID (atau mungkin lebih tepatnya, itu Protokol Email Terverifikasi) dengan semangat menemukan jalur peningkatan ke pendekatan yang lebih baik untuk otentikasi di masa depan.

Saya akan meringkasnya seperti ini:

  1. Mozilla adalah lembaga nonprofit dengan nilai-nilai yang selaras dengan baik dengan mencari solusi yang baik untuk masalah ini.
  2. Kenyataannya saat ini adalah sebagian besar situs web menggunakan autentikasi berbasis formulir
  3. Otentikasi berbasis form memiliki kerugian besar, yang meningkatkan risiko phishing. Pengguna diminta untuk memasukkan informasi sensitif ke dalam area yang dikendalikan oleh entitas jauh, daripada area yang dikendalikan oleh Agen Pengguna mereka (browser).
  4. Karena browser secara implisit tepercaya (seluruh ide Agen Pengguna adalah bertindak atas nama Pengguna), mereka dapat membantu memperbaiki situasi ini.
  5. Kekuatan utama menahan kemajuan di sini adalah deadlock penyebaran. Solusi harus diuraikan menjadi langkah-langkah yang memberikan beberapa manfaat tambahan pada mereka sendiri.
  6. Metode terdesentralisasi paling sederhana untuk mengekspresikan identitas yang dibangun ke dalam infrastruktur internet adalah nama domain.
  7. Sebagai level kedua untuk mengekspresikan identitas, setiap domain mengelola kumpulan akunnya sendiri.
  8. Bentuk “akun@domain "ringkas dan didukung oleh berbagai protokol dan skema URI. Pengidentifikasi semacam itu, tentu saja, paling dikenal secara universal sebagai alamat email.
  9. Penyedia email sudah menjadi penyedia identitas utama de-facto online. Alur penyetelan ulang sandi saat ini biasanya memungkinkan Anda mengendalikan akun jika Anda dapat membuktikan bahwa Anda mengontrol alamat email terkait akun tersebut.
  10. Protokol Email yang Diverifikasi diusulkan untuk menyediakan metode aman, berdasarkan kriptografi kunci publik, untuk menyederhanakan proses pembuktian ke domain B bahwa Anda memiliki akun di domain A.
  11. Untuk browser yang tidak mendukung Verified Email Protocol (sekarang semuanya), Mozilla menyediakan shim yang mengimplementasikan protokol dalam kode JavaScript sisi-klien.
  12. Untuk layanan email yang tidak mendukung Protokol Email Terverifikasi, protokol tersebut memungkinkan pihak ketiga bertindak sebagai perantara tepercaya, menegaskan bahwa mereka telah memverifikasi kepemilikan akun oleh pengguna. Tidak diinginkan memiliki banyak pihak ketiga seperti itu; kemampuan ini hanya ditujukan untuk memungkinkan jalur peningkatan, dan lebih disukai bahwa layanan email memberikan pernyataan ini sendiri.
  13. Mozilla menawarkan layanan mereka sendiri untuk bertindak sebagai pihak ketiga tepercaya. Penyedia Layanan (yaitu, Mengandalkan Pihak) yang menerapkan Protokol Email Terverifikasi dapat memilih untuk mempercayai pernyataan Mozilla atau tidak. Layanan Mozilla memverifikasi kepemilikan akun pengguna menggunakan cara konvensional mengirim email dengan tautan konfirmasi.
  14. Penyedia Layanan dapat, tentu saja, menawarkan protokol ini sebagai pilihan selain metode lain otentikasi yang mungkin ingin mereka tawarkan.
  15. Manfaat antarmuka pengguna besar yang dicari di sini adalah "pemilih identitas". Ketika seorang pengguna mengunjungi situs dan memilih untuk mengautentikasi, browser mereka menunjukkan kepada mereka pilihan alamat email ("pribadi", "kerja", "aktivisme politik", dll.) Yang dapat mereka gunakan untuk mengidentifikasi diri mereka ke situs.
  16. Manfaat antarmuka pengguna besar lainnya yang sedang dicari sebagai bagian dari upaya ini membantu peramban mengetahui lebih banyak tentang sesi pengguna - siapa yang mereka masuki saat ini, terutama - sehingga dapat menampilkannya di browser chrome.
  17. Karena sifat terdistribusi dari sistem ini, ia menghindari lock-in ke situs-situs besar seperti Facebook, Twitter, Google, dll. Setiap individu dapat memiliki domain mereka sendiri dan karena itu bertindak sebagai penyedia identitas mereka sendiri.

Ini bukan "otentikasi berbasis form untuk situs web" yang ketat. Tetapi ini adalah upaya untuk beralih dari norma saat ini dari otentikasi berbasis form ke sesuatu yang lebih aman: otentikasi yang didukung browser.


146



Saya hanya berpikir saya akan berbagi solusi yang menurut saya berfungsi dengan baik.

Saya menyebutnya Dummy Field (meskipun saya belum menemukan ini jadi jangan kredit saya).

Singkatnya: Anda hanya perlu memasukkan ini ke Anda <form> dan periksa apakah kosong saat memvalidasi:

<input type="text" name="email" style="display:none" />

Triknya adalah membodohi bot dengan mengira harus memasukkan data ke bidang yang diperlukan, itulah mengapa saya memberi nama "email" masukan. Jika Anda sudah memiliki bidang yang disebut surel yang Anda gunakan, Anda harus mencoba memberi nama bidang dummy yang lain seperti "perusahaan", "telepon" atau "alamat email". Pilihlah sesuatu yang Anda tahu tidak Anda perlukan dan apa yang terdengar seperti sesuatu yang biasanya orang temukan logis untuk mengisi formulir web. Sekarang sembunyikan input bidang menggunakan CSS atau JavaScript / jQuery - apa pun yang paling cocok untuk Anda - hanya tidak mengatur input type untuk hidden atau bot tidak akan jatuh untuk itu.

Ketika Anda memvalidasi formulir (baik klien atau sisi server) periksa apakah bidang dummy Anda telah diisi untuk menentukan apakah itu dikirim oleh manusia atau bot.

Contoh:

Dalam kasus manusia: Pengguna tidak akan melihat bidang dummy (dalam kasus saya bernama "email") dan tidak akan mencoba untuk mengisinya. Jadi nilai bidang dummy harus tetap kosong ketika formulir telah dikirim.

Dalam kasus bot: Bot akan melihat bidang yang bertipe text dan sebuah nama email (atau apa pun namanya Anda) dan secara logis akan mencoba mengisinya dengan data yang sesuai. Tidak peduli jika Anda menata bentuk input dengan beberapa CSS yang mewah, pengembang web melakukannya sepanjang waktu. Apa pun nilainya di bidang boneka, kita tidak peduli asalkan lebih besar 0 karakter.

Saya menggunakan metode ini pada buku tamu yang dikombinasikan dengan CAPTCHA, dan saya belum pernah melihat satu pun pos spam sejak itu. Saya telah menggunakan solusi CAPTCHA saja, tetapi akhirnya menghasilkan sekitar lima posting spam setiap jam. Menambahkan bidang dummy dalam bentuk telah berhenti (setidaknya sampai sekarang) semua spam tidak muncul.

Saya yakin ini juga dapat digunakan dengan baik dengan formulir masuk / otentikasi.

PERINGATAN: Tentu saja metode ini tidak 100% bukti bodoh. Bot dapat diprogram untuk mengabaikan bidang masukan dengan gaya display:none diterapkan padanya. Anda juga harus berpikir tentang orang-orang yang menggunakan beberapa bentuk pelengkapan otomatis (seperti kebanyakan browser telah built-in!) Untuk mengisi otomatis semua kolom formulir untuk mereka. Mereka mungkin juga mengambil bidang boneka.

Anda juga dapat sedikit berbeda dengan membiarkan bidang boneka terlihat tetapi di luar batas layar, tetapi ini sepenuhnya terserah Anda.

Jadilah kreatif!


120



Saya tidak berpikir jawaban di atas adalah "salah" tetapi ada area besar otentikasi yang tidak tersentuh (atau lebih tepatnya penekanannya adalah pada "bagaimana mengimplementasikan sesi cookie", bukan pada "opsi apa yang tersedia dan apa perdagangan off ".

Pengeditan / jawaban saya yang disarankan adalah

  • Masalahnya terletak lebih pada pengaturan akun daripada dalam pemeriksaan kata sandi.
  • Penggunaan authenitikasi dua faktor jauh lebih aman daripada cara enkripsi kata sandi yang lebih pintar
  • JANGAN mencoba untuk mengimplementasikan login form Anda sendiri atau penyimpanan basis data kata sandi, kecuali data yang disimpan tidak berharga di kreasi akun dan dibuat sendiri (yaitu, gaya web 2.0 seperti Facebook, Flickr, dll.)

    1. Otentikasi Digest adalah pendekatan berbasis standar yang didukung di semua browser dan server utama, yang tidak akan mengirim kata sandi bahkan melalui saluran aman.

Ini menghindari setiap kebutuhan untuk memiliki "sesi" atau cookie karena peramban itu sendiri akan mengenkripsi ulang komunikasi setiap kali. Ini adalah pendekatan pengembangan yang paling "ringan".

Namun, saya tidak merekomendasikan ini, kecuali untuk layanan publik, nilai rendah. Ini adalah masalah dengan beberapa jawaban lain di atas - jangan coba mengimplementasikan kembali mekanisme autentikasi sisi server - masalah ini telah diselesaikan dan didukung oleh sebagian besar browser. Jangan gunakan cookie. Jangan simpan apa pun di dalam database linting tangan Anda sendiri. Tanyakan saja, per permintaan, jika permintaan tersebut diautentikasi. Segala sesuatu yang lain harus didukung oleh konfigurasi dan perangkat lunak tepercaya pihak ketiga.

Jadi ...

Pertama, kami membingungkan pembuatan awal akun (dengan kata sandi) dengan pengecekan ulang kata sandi selanjutnya. Jika saya Flickr dan membuat situs Anda untuk pertama kalinya, pengguna baru memiliki akses ke nilai nol (ruang web kosong). Saya benar-benar tidak peduli jika orang yang membuat akun berbohong tentang nama mereka. Jika saya membuat akun intranet / extranet rumah sakit, nilainya ada di semua catatan medis, jadi saya melakukan peduli tentang identitas (*) dari pencipta akun.

Ini adalah bagian yang sangat sulit. Itu hanya solusi yang layak adalah jaringan kepercayaan. Misalnya, Anda bergabung dengan rumah sakit sebagai dokter. Anda membuat halaman web yang dihosting di suatu tempat dengan foto Anda, nomor paspor Anda dan kunci publik, dan hash semuanya dengan kunci pribadi. Anda kemudian mengunjungi rumah sakit dan administrator sistem melihat paspor Anda, melihat apakah foto cocok dengan Anda, dan kemudian mem-hash halaman web / foto dengan kunci pribadi rumah sakit. Mulai sekarang kita dapat saling bertukar kunci dan token secara aman. Seperti siapa pun yang mempercayai rumah sakit (ada saus rahasia BTW). Administrator sistem juga dapat memberi Anda RSA dongle atau otentikasi dua faktor lainnya.

Tapi ini a banyak kerumitan, dan tidak terlalu web 2.0. Namun, ini adalah satu-satunya cara aman untuk membuat akun baru yang memiliki akses ke informasi berharga yang tidak dibuat sendiri.

  1. Kerberos dan SPNEGO - tanda tunggal pada mekanisme dengan pihak ketiga tepercaya - pada dasarnya pengguna memverifikasi terhadap pihak ketiga tepercaya. (NB ini bukan cara yang tidak bisa dipercaya OAuth)

  2. SRP - semacam otentikasi kata sandi pintar tanpa pihak ketiga yang tepercaya. Tapi di sini kita masuk ke dunia "lebih aman menggunakan otentikasi dua faktor, bahkan jika itu lebih mahal"

  3. SSL sisi klien - memberikan klien sertifikat kunci publik (dukungan di semua browser utama - tetapi menimbulkan pertanyaan atas keamanan mesin klien).

Pada akhirnya itu adalah tradeoff - berapa biaya pelanggaran keamanan vs biaya penerapan pendekatan yang lebih aman. Suatu hari, kita mungkin melihat yang tepat PKI diterima secara luas sehingga tidak ada lagi formulir dan database otentikasi yang digulirkan. Suatu hari...


71



Ketika hashing, jangan gunakan algoritma hash cepat seperti MD5 (banyak perangkat keras yang ada). Gunakan sesuatu seperti SHA-512. Untuk kata sandi, hash yang lebih lambat lebih baik.

Semakin cepat Anda dapat membuat hash, semakin cepat setiap pemeriksa kekuatan kasar dapat bekerja. Kurungan yang lebih lambat karenanya akan memperlambat pemaksaan brute. Algoritma hash yang lambat akan membuat brute forcing tidak praktis untuk password yang lebih panjang (8 digit +)


48



Artikel bagus tentang perkiraan kekuatan sandi realistis adalah:

Dropbox Tech Blog »Blog Archive» zxcvbn: estimasi kekuatan kata sandi yang realistis


46



Aturan favorit saya dalam hal sistem otentikasi: gunakan passphrase, bukan kata sandi. Mudah diingat, sulit dipecahkan. Info lebih lanjut: Coding Horror: Kata Sandi vs. Pass Phrases


41



Saya ingin menambahkan satu saran yang saya gunakan, berdasarkan pertahanan secara mendalam. Anda tidak perlu memiliki sistem auth & autentikasi yang sama untuk admin sebagai pengguna biasa. Anda dapat memiliki formulir masuk terpisah pada url terpisah yang mengeksekusi kode terpisah untuk permintaan yang akan memberikan hak istimewa yang tinggi. Yang satu ini bisa membuat pilihan yang akan sangat menyakitkan bagi pengguna biasa. Salah satu yang saya gunakan adalah benar-benar mengacak URL masuk untuk akses admin dan mengirim email kepada admin URL baru. Menghentikan serangan brute force segera karena URL baru Anda dapat sewenang-wenang sulit (string acak yang sangat panjang) tetapi ketidaknyamanan hanya pengguna admin Anda mengikuti tautan di email mereka. Penyerang tidak lagi tahu ke mana POST menjadi.


20



Saya tidak tahu apakah sebaiknya menjawab ini sebagai jawaban atau sebagai komentar. Saya memilih opsi pertama.

Mengenai poing BAGIAN IV: Fungsionalitas Kata Sandi yang Terlupakan dalam jawaban pertama, saya akan membuat point tentang Serangan Timing.

Dalam Ingat kata sandi Anda formulir, penyerang berpotensi memeriksa daftar lengkap email dan mendeteksi yang terdaftar ke sistem (lihat tautan di bawah).

Mengenai Formulir Kata Sandi yang Terlupakan, saya akan menambahkan bahwa itu adalah ide yang baik untuk menyamakan waktu antara kueri yang sukses dan unsucessful dengan beberapa fungsi penundaan.

https://crypto.stanford.edu/~dabo/papers/webtiming.pdf


12