Misalkan saya memiliki REST API yang juga digunakan untuk mengatur / mengatur ulang kata sandi. Mari kita juga anggap ini berfungsi melalui koneksi HTTPS. Apakah ada alasan bagus untuk tidak meletakkan kata sandi itu di jalur panggilan, katakan juga saya akan menyandikannya di BASE64?
Contohnya adalah mengatur ulang kata sandi seperti ini:
http://www.example.com/user/joe/resetpassword/OLDPASSWD/NEWPASSWD
Saya mengerti BASE64 bukan enkripsi, tapi saya hanya ingin melindungi kata sandi untuk berselancar di bahu dalam kasus ini.
resetpassword/OLDPASSWD/NEWPASSWD
bukan sumber daya. Ini doa dari suatu proses. Anda tidak perlu memasukkan semuanya ke dalam URL.Jawaban:
Server yang baik mencatat semua permintaan yang dikirim ke sana, termasuk URL (sering, tanpa bagian variabel setelah '?'), IP sumber, waktu eksekusi ... Apakah Anda benar-benar ingin log ini (berpotensi dibaca oleh grup admin yang luas) mengandung info sangat kritis sebagai kata sandi? Base64 bukan penghenti mereka.
sumber
Apa yang Anda usulkan tidak aman atau tenang.
@Netch telah menyebutkan masalah dengan log, tetapi ada juga masalah lain di mana Anda menunjukkan kata sandi dikirim oleh HTTP, membuatnya sepele untuk menangkap kata sandi dengan segala jenis sniffer kawat atau serangan manusia-di-tengah.
Saat Anda melakukan permintaan GET menggunakan REST, elemen berbeda di URL mewakili elemen berbutir halus. URL Anda berbunyi seperti Anda mengembalikan bagian NEWPASSWD dari OLDPASSWD yang merupakan bagian dari kata sandi reset. Itu tidak masuk akal semantik. GET tidak boleh digunakan untuk menyimpan data.
Anda harus melakukan sesuatu seperti ini:
POST karena Anda menulis data, dan https karena Anda tidak ingin mengendusnya.
(Ini benar-benar keamanan bar rendah. Minimum absolut yang harus Anda lakukan.)
sumber
/user/joe/password
sedikit lebih baik tetapi tidak optimal.PUT
, karenaPUT
idempoten. Tetapi ketika kata sandi telah diubah darisecret
menjadisupersecret
berhasil, maka permintaan yang sama akan gagal untuk kedua kalinya, jadiPOST
benar di sini. Tentu saja, seperti yang dikatakan @whirlwin, sumber ini tidak disebutkan namanya.Skema yang diusulkan memiliki masalah di beberapa bidang.
Keamanan
Jalur URL sering dicatat; menempatkan kata sandi yang tidak diacuhkan di jalan adalah praktik yang buruk.
HTTP
Informasi otentikasi / otorisasi akan muncul di header Otorisasi. Atau berpotensi, untuk hal-hal berbasis browser, header Cookie.
BERISTIRAHAT
Kata kerja seperti
resetpassword
di URL Anda umumnya merupakan tanda yang jelas dari paradigma transfer negara non-representasional. URL harus mewakili sumber daya. Apa artinya GETresetpassword
? Atau HAPUS?API
Skema ini mengharuskan selalu mengetahui kata sandi sebelumnya. Anda mungkin ingin mengizinkan lebih banyak kasus; mis. kata sandi hilang.
Anda bisa menggunakan otentikasi Dasar atau Intisari , yang merupakan skema yang dipahami dengan baik.
Itu tidak menempatkan informasi ultra-sensitif di jalur, dan mengikuti konvensi HTTP dan REST.
Jika Anda perlu mengizinkan beberapa mode otorisasi lainnya (mis. Beberapa token yang dikirim melalui saluran terverifikasi untuk mereset kata sandi), Anda dapat menggunakan tajuk Otorisasi yang berbeda tanpa harus mengubah apa pun.
sumber
Terlepas dari keamanan, masalah dengan ini adalah bahwa itu bukan pendekatan yang sangat tenang.
OLDPASSWD
danNEWPASSWD
tidak mendukung apa pun dalam hierarki sumber daya Anda dan bahkan lebih buruk lagi, operasinya tidak idempoten.Jadi Anda hanya dapat menggunakan
POST
kata kerja Anda, dan Anda tidak harus memasukkan dua kata sandi di jalur sumber daya Anda.sumber
PUT
didiskualifikasi sebagai kata kerja. Itu bisa digabung ulang untuk bekerja denganPUT
tetapi dalam bentuk saat ini tidak.Masalahnya adalah untuk menghindari kata sandi teks biasa dalam permintaan Anda. Ada dua opsi untuk memenuhi persyaratan layanan web yang tenang.
1. hashing sisi klien
2. Enkripsi
Catatan: HTTPS diperlukan untuk kedua opsi!
sumber
Apa saja fitur operasi reset kata sandi?
Poin 1 di sini berarti Anda tidak dapat menggunakan GET, Anda harus POST sesuatu yang mewakili operasi penggantian kata sandi ke URI yang mewakili sumber daya yang menangani perubahan kata sandi, atau PUT sesuatu yang mewakili kata sandi baru ke URI yang mewakili kata sandi atau mewakili sesuatu (misalnya pengguna) yang kata sandinya adalah fitur.
Secara umum kami akan POST, paling tidak karena itu bisa menjadi canggung. PUTting sesuatu yang tidak bisa kami dapatkan nanti dan tentu saja kami tidak bisa MENDAPATKAN kata sandi.
Oleh karena itu, poin 2 adalah data yang mewakili kata sandi baru, dalam apa yang POST.
Poin 3 berarti kita harus mengesahkan permintaan, yang berarti bahwa jika pengguna adalah pengguna saat ini, kita akan memerlukan kata sandi saat ini untuk dibuktikan kepada kita (meskipun tidak harus menerima kata sandi saat ini, jika misalnya tantangan berbasis hash digunakan untuk membuktikan pengetahuan tentang itu tanpa mengirimnya).
Karena itu URI harus seperti
<http://example.net/changeCurrentUserPassword>
atau<http://example.net/users/joe/changePassword>
.Kami mungkin memutuskan bahwa kami ingin menerima kata sandi saat ini dalam data POST serta dalam mekanisme otorisasi umum yang digunakan.
sumber