Keamanan skema otentikasi REST

228

Latar Belakang:

Saya sedang merancang skema otentikasi untuk layanan web REST. Ini tidak "benar-benar" perlu aman (ini lebih merupakan proyek pribadi) tetapi saya ingin membuatnya seaman mungkin sebagai pengalaman latihan / belajar. Saya tidak ingin menggunakan SSL karena saya tidak ingin kerumitan dan, sebagian besar, biaya pengaturannya.

Pertanyaan SO ini sangat berguna untuk memulai saya:

Saya sedang berpikir untuk menggunakan versi sederhana dari otentikasi Amazon S3 (saya suka OAuth tetapi tampaknya terlalu rumit untuk kebutuhan saya). Saya menambahkan nonce yang dibuat secara acak , disediakan oleh server, ke permintaan, untuk mencegah serangan replay.

Untuk sampai ke pertanyaan:

S3 dan OAuth bergantung pada penandatanganan URL permintaan bersama dengan beberapa header yang dipilih. Tak satu pun dari mereka menandatangani badan permintaan untuk permintaan POST atau PUT. Bukankah ini rentan terhadap serangan orang-di-tengah, yang menjaga url dan header dan menggantikan tubuh permintaan dengan data yang diinginkan penyerang?

Sepertinya saya bisa menjaga ini dengan memasukkan hash dari tubuh permintaan dalam string yang ditandatangani. Apakah ini aman?

dF.
sumber
6
Amazon S3 dapat menyertakan Content-MD5 sebagai bagian dari string tajuk untuk mencegah serangan MITM yang Anda gambarkan.
laz
8
MD5 adalah fungsi hash yang sangat lemah dan penggunaannya telah tidak disarankan selama bertahun-tahun sekarang: en.wikipedia.org/wiki/MD5 . Gunakan SHA2 saat ini. MD5 adalah lipstik pada babi dengan krisis identitas.
Henrik
6
Startcom menyediakan sertifikat SSL gratis yang tidak membuang peringatan sertifikat di peramban utama
Plato
5
@SKAKAnderson (kata-kata kasar: Saya merasa tidak masuk akal bagaimana orang berbicara tentang 99,99999% ketika internet dikepung oleh agen mata-mata yang telah mengotomatiskan BANYAK serangan pada 2008 - itu cara yang aneh untuk menangani masalah nyata - "Naaah, tidak akan menjadi masalah; bagi nenekku tidak akan bisa meretasnya"
Henrik
2
@ Plato Saya akan merekomendasikan LetsEncrypt hari ini untuk sertifikat SSL gratis
shuttle87

Jawaban:

168

Jawaban sebelumnya hanya menyebutkan SSL dalam konteks transfer data dan sebenarnya tidak mencakup otentikasi.

Anda benar-benar bertanya tentang mengautentikasi klien REST API dengan aman. Kecuali Anda menggunakan otentikasi klien TLS, SSL saja BUKAN mekanisme otentikasi yang layak untuk API REST. SSL tanpa authc klien hanya mengotentikasi server , yang tidak relevan untuk sebagian besar API REST karena Anda benar-benar ingin mengautentikasi klien .

Jika Anda tidak menggunakan otentikasi klien TLS, Anda harus menggunakan sesuatu seperti skema otentikasi berbasis intisari (seperti skema kustom Amazon Web Service) atau OAuth 1.0a atau bahkan otentikasi HTTP Basic (tetapi hanya untuk SSL saja).

Skema ini mengotentikasi bahwa permintaan dikirim oleh seseorang yang diharapkan. TLS (SSL) (tanpa otentikasi klien) memastikan bahwa data yang dikirim melalui kabel tetap tidak teramplas. Mereka terpisah - tetapi saling melengkapi - perhatian.

Bagi mereka yang tertarik, saya telah memperluas pertanyaan SO tentang Skema Otentikasi HTTP dan cara kerjanya .

Les Hazlewood
sumber
16
Persis. Satu-satunya hal yang diverifikasi oleh SSL sejauh menyangkut API Anda adalah bahwa panggilan yang dihadapinya belum dikacaukan dalam perjalanan. API masih tidak tahu siapa yang berbicara dengannya atau apakah mereka harus memiliki akses atau tidak.
Tim Gautier
1
Jawaban yang bagus. Saya juga merekomendasikan memiliki melihat sumber daya yang sangat baik .. owasp.org/index.php/Web_Service_Security_Cheat_Sheet dan owasp.org/index.php/REST_Security_Cheat_Sheet (DRAFT)
dodgy_coder
2
Hanya titik kecil, tetapi menggunakan SSL juga memiliki manfaat tambahan untuk mencegah penyadapan dan orang-orang di serangan tengah.
dodgy_coder
@Les Hazlewood Bisakah Anda menjelaskan bagaimana otentikasi HTTP Basic melalui Https dapat membantu menentukan server yang tahu siapa yang berbicara?
Musim Semi
@Les Hazlewood di sini saya bertanya dalam sebuah pertanyaan; tnx stackoverflow.com/questions/14043397/…
Musim Semi
60

REST berarti bekerja dengan standar web, dan standar untuk transfer "aman" di web adalah SSL. Hal lain akan menjadi agak funky dan membutuhkan upaya penyebaran tambahan untuk klien, yang harus memiliki perpustakaan enkripsi yang tersedia.

Setelah Anda berkomitmen ke SSL, pada prinsipnya tidak ada yang diperlukan untuk otentikasi. Anda dapat kembali menggunakan standar web dan menggunakan HTTP Basic auth (nama pengguna dan token rahasia yang dikirimkan bersama dengan setiap permintaan) karena jauh lebih sederhana daripada protokol penandatanganan yang rumit, dan masih efektif dalam konteks koneksi yang aman. Anda hanya perlu memastikan kata sandi tidak pernah melampaui teks biasa; jadi jika kata sandi tersebut pernah diterima melalui koneksi teks biasa, Anda bahkan dapat menonaktifkan kata sandi dan mengirimkan email kepada pengembang. Anda juga harus memastikan kredensial tidak dicatat di mana pun setelah diterima, sama seperti Anda tidak akan mencatat kata sandi biasa.

HTTP Digest adalah pendekatan yang lebih aman karena mencegah token rahasia yang diteruskan; alih-alih, ini adalah hash yang dapat diverifikasi server di ujung lainnya. Meskipun mungkin berlebihan untuk aplikasi yang kurang sensitif jika Anda telah mengambil tindakan pencegahan yang disebutkan di atas. Lagipula, kata sandi pengguna sudah dikirim dalam teks biasa ketika mereka masuk (kecuali jika Anda melakukan enkripsi JavaScript yang bagus di browser), dan juga cookie mereka pada setiap permintaan.

Perhatikan bahwa dengan API, lebih baik bagi klien untuk melewati token - string yang dibuat secara acak - daripada kata sandi yang dibuat oleh pengembang untuk masuk ke situs web. Jadi pengembang harus dapat masuk ke situs Anda dan menghasilkan token baru yang dapat digunakan untuk verifikasi API.

Alasan utama untuk menggunakan token adalah bahwa token dapat diganti jika dikompromikan, sedangkan jika kata sandi dikompromikan, pemilik dapat masuk ke akun pengembang dan melakukan apa pun yang mereka inginkan dengannya. Keuntungan lebih lanjut dari token adalah Anda dapat mengeluarkan beberapa token ke pengembang yang sama. Mungkin karena mereka memiliki beberapa aplikasi atau karena mereka ingin token dengan tingkat akses yang berbeda.

(Diperbarui untuk mencakup implikasi membuat koneksi hanya SSL.)

mahemoff
sumber
3
Anda bisa mendapatkan sertifikat GoDaddy ssl seharga $ 30 setahun menurut saya. Saya terkejut melihat berapa banyak sertifikat SSL Verisign ($ 600 setahun atau sesuatu jika saya ingat dengan benar?) Tetapi opsi GoDaddy sangat mungkin dilakukan.
Brian Armstrong
19
Kecuali Anda menggunakan otentikasi timbal balik SSL / TLS, dan sertifikat yang digunakan oleh pengguna / klien dipercaya oleh server, maka Anda belum mengautentikasi pengguna ke server / aplikasi. Anda perlu melakukan sesuatu yang lebih untuk mengotentikasi pengguna ke server / aplikasi.
Pauld
5
Ryan: enkripsi SSL hari ini membutuhkan jumlah yang cukup kecil kekuatan pemrosesan dibandingkan dengan apa yang akan Anda gunakan untuk menghasilkan respon dengan kerangka aplikasi web seperti Django atau Rails dll
Cameron Walsh
4
sertifikat dari startcom gratis dan dikenal luas. cacert.org adalah alternatif terbuka dengan sedikit pengakuan
Dima Tisnek
17
Ini tidak menjawab pertanyaan, yaitu tentang otentikasi.
Sam Stainsby
8

Atau Anda bisa menggunakan solusi yang diketahui untuk masalah ini dan menggunakan SSL. Sertifikat yang ditandatangani sendiri bebas dan ini proyek pribadi, kan?

wowest
sumber
2
Sertifikat yang ditandatangani sendiri gratis, tetapi AFAIK Anda masih membutuhkan IP statis.
dF.
8
@dF tidak ada persyaratan untuk memiliki IP statis kecuali untuk persyaratan lisensi komersial tertentu yang dibayar untuk sertifikat.
Chris Marisic
Jika Anda memiliki kendali atas toko sertifikat di kedua ujungnya (klien & server) ini mungkin merupakan opsi yang layak tetapi ... manajemen dan distribusi sertifikat mungkin jauh lebih kompleks dalam produksi daripada di lingkungan pengembangan. Pastikan untuk memahami kompleksitas dari alternatif ini sebelum berkomitmen untuk itu.
aled
5

Jika Anda memerlukan hash body sebagai salah satu parameter dalam URL dan URL itu ditandatangani melalui kunci pribadi, maka serangan man-in-the-middle hanya akan dapat menggantikan tubuh dengan konten yang akan menghasilkan hash yang sama. Mudah dilakukan dengan nilai hash MD5 sekarang setidaknya dan ketika SHA-1 rusak, Anda mendapatkan gambar.

Untuk mengamankan tubuh dari gangguan, Anda harus memerlukan tanda tangan dari tubuh, yang kemungkinan serangannya tidak dapat dilakukan karena serangan dari orang yang berada di tengah tidak akan mengetahui kunci pribadi yang menghasilkan tanda tangan tersebut. .

ZaDDaZ
sumber
9
Menghasilkan string yang akan menghasilkan hash md5 yang sama karena konten yang valid mungkin jauh lebih mudah dari yang seharusnya, tetapi membuat versi jahat konten yang valid yang hash dengan nilai yang sama masih sangat sulit. Inilah sebabnya mengapa md5 tidak digunakan untuk hash kata sandi lagi, tetapi masih digunakan untuk memverifikasi unduhan.
Tim Gautier
1

Ingatlah bahwa saran Anda mempersulit klien untuk berkomunikasi dengan server. Mereka perlu memahami solusi inovatif Anda dan mengenkripsi data yang sesuai, model ini tidak begitu baik untuk API publik (kecuali jika Anda amazon \ yahoo \ google ..).

Bagaimanapun, jika Anda harus mengenkripsi konten tubuh saya sarankan Anda untuk memeriksa standar dan solusi yang ada seperti:

Enkripsi XML (standar W3C)

Keamanan XML

LiorH
sumber