Prom dan skop
Ini ialah masalah protokol OAuth dan reka bentuk keselamatan. RFC 8628 menyasarkan TV pintar, konsol media, pencetak dan peranti serupa yang tidak dapat memasukkan teks dengan mudah atau menjalankan pelayar. Peranti meminta device_code dan user_code; pengguna log masuk dan memberi kebenaran pada pelayar yang berasingan; peranti asal melakukan pengundian pada titik akhir token. Peranti sedemikian biasanya merupakan klien awam dan tidak dapat menyembunyikan rahsia klien jangka panjang dalam perisian tegar (firmware). Latihan ini tidak menggantikan aliran kod kebenaran untuk aplikasi natif yang boleh menggunakan pelayar sistem.
Perkara yang diuji oleh penemu duga
- Membezakan jangka hayat device code, user code, URI pengesahan, token akses dan token muat semula.
- Memetakan
authorization_pending,slow_down,expired_token, danaccess_deniedkepada keadaan. - Mereka bentuk pengundian terikat, backoff, kedayapancaman (idempotency) dan perlindungan keserentakan.
- Mengenal pasti pancingan data user code, penyamaran peranti, tekaan kekerasan (brute-force) dan risiko klien awam.
Penjelasan untuk ditanya terlebih dahulu
Sahkan sama ada peranti boleh memaparkan URI dan kod, membuat permintaan HTTPS dan mengekalkan jam yang boleh dipercayai, serta sama ada pelayan kebenaran menyokong log masuk OIDC. Jelaskan sumber yang diminta, pengikatan peranti, pihak yang menetapkan jangka hayat kod dan selang pengundian, serta sama ada pembatalan diperlukan. Jika peranti sudah mempunyai pelayar sistem, utamakan aliran kod kebenaran RFC 8252 daripada memaksa Device Flow.
Jawapan 30 saat
Laksanakan dua titik akhir. Titik akhir kebenaran peranti mengembalikan device_code jangka pendek, user_code yang dimasukkan manusia, verification_uri, tamat tempoh dan selang minimum. Titik akhir token hanya menerima device code dan mengembalikan token atau ralat standard. Simpan cincangan (hash) device code, status, klien dan tamat tempoh. Lakukan pengundian pada selang yang disediakan pelayan: teruskan pada authorization_pending, tingkatkan selang pada slow_down, dan berhenti apabila berjaya, tamat tempoh, penolakan atau ketidaksahan kekal. Tunjukkan maklumat peranti pada halaman pengguna untuk mengurangkan pancingan data.
Penyelesaian langkah demi langkah
1. Modelkan peserta dan satu sesi kebenaran
Peserta ialah peranti terhad, pelayan kebenaran, pelayar pengguna dan pelayan sumber. Titik akhir kebenaran peranti mencipta sesi dengan device_code entropi tinggi, user_code yang mudah dimasukkan, klien, skop yang diminta, masa penciptaan, tamat tempoh dan keadaan pengundian. Simpan hanya ikhtisar sehala (one-way digest) bagi device code supaya bacaan pangkalan data tidak terus mencetak token; indekskan user code secara berasingan dan hadkan percubaan.
2. Reka bentuk respons kebenaran peranti
Kembalikan sekurang-kurangnya device_code, user_code, verification_uri, expires_in, dan interval. verification_uri_complete boleh menawarkan pautan yang mudah, tetapi paparkan kod pendek yang sama pada peranti dan halaman pengguna serta minta pengguna mengesahkan peranti di hadapan mereka. Lindungi kod daripada log, analitik dan tangkapan skrin. Pelayan tidak boleh meletakkan token akses dalam respons ini.
3. Kendalikan interaksi dan pengikatan pengguna
Selepas membuka URI pengesahan, pengguna log masuk dan melihat nama klien, skop yang diminta dan maklumat peranti. Halaman persetujuan harus meminta pengguna mengesahkan bahawa peranti itu milik mereka, bagi mengurangkan kebenaran peranti penyerang. Kelulusan menukar sesi kepada AUTHORIZED; ia tidak menghantar token melalui pelayar ke peranti. Penolakan ialah keadaan terminal DENIED yang dilaporkan secara eksplisit oleh pengundian seterusnya.
4. Tentukan mesin keadaan titik akhir token
Titik akhir token memacu keadaan peranti dengan ralat standard:
poll(device_code):
session = lookup(hash(device_code))
if session is missing: return invalid_grant
if now >= session.expiresAt: return expired_token
if session.status == DENIED: return access_denied
if session.status != AUTHORIZED: return authorization_pending
atomically mark CONSUMED
return issueAccessAndRefreshTokens(session)Penebusan yang berjaya bagi satu device code mestilah atomik supaya dua bebenang (threads) peranti tidak boleh menerima dua set token. Jika kod adalah untuk kegunaan sekali sahaja, permintaan berulang akan mengembalikan invalid_grant atau ralat protokol yang menunjukkan ia telah digunakan; percubaan semula yang gagal tidak boleh mencipta sesi kebenaran baharu.
5. Gunakan backoff pengundian dan perlindungan pelayan
Peranti tidak boleh melakukan pengundian lebih awal daripada interval respons. Kekalkan selang tersebut selepas authorization_pending; selepas slow_down, tingkatkannya sekurang-kurangnya 5 saat. Tambahkan tarikh akhir keseluruhan, tamat masa rangkaian dan jitter pada peranti. Hadkan kadar (rate-limit) mengikut device code, klien dan IP pada pelayan. Respons token harus melarang caching supaya perantara tidak memainkan semula keadaan; semasa beban tinggi, kembalikan ralat yang boleh dicuba semula daripada mencipta tugas latar belakang yang mahal bagi setiap pengundian.
6. Kendalikan tamat tempoh, pembatalan dan pemulihan
Anggap expired_token, access_denied, dan invalid_grant kekal sebagai terminal. Kosongkan device code setempat dan hentikan pengundian. Tindakan pembatalan peranti menandakan sesi sebagai CANCELLED; permintaan kemudian tidak boleh menghidupkannya semula. Semasa gangguan rangkaian, kekalkan tarikh akhir dan sambung semula kod yang sama daripada mencipta beberapa sesi yang boleh membenarkan peranti yang salah. Selepas but semula, mulakan semula dan beritahu pengguna jika peranti tidak dapat mengekalkan keadaan sesi secara selamat.
7. Lindungi klien awam dan tahan pancingan data
Anggap peranti tidak dapat melindungi rahsia klien. Minimumkan skop, serta putar dan batalkan token muat semula. Jadikan user code cukup pendek untuk dimasukkan tetapi cukup rawak untuk menahan tekaan dalam talian; hadkan kadar percubaan yang gagal mengikut kod dan IP. Tunjukkan nama peranti, model atau kod sekali guna dan minta pengguna membandingkannya dengan skrin. Log hanya mengandungi ID sesi, hasil dan pengecam yang dicincang, tidak sekali-kali device code mentah atau token.
8. Pasang instrumen dan uji aliran
Ukur penciptaan kebenaran peranti, penyempurnaan, masa untuk diselesaikan, pengundian setiap sesi, kadar slow_down, tamat tempoh dan penolakan, serta perlumbaan (race condition) penebusan token. Uji penebusan pendua, tamat masa, herotan jam (clock skew), percubaan semula rangkaian, tekaan, pengundian serentak, penolakan pengguna, permulaan semula pelayan dan pendikit (throttling). Ujian hujung ke hujung mesti membuktikan bahawa peranti yang diluluskan dan sesi token akhir sepadan; dua titik akhir yang mengembalikan 200 secara berasingan adalah tidak mencukupi.
Jawapan model
Saya akan mencipta sesi RFC 8628 sekali guna. Titik akhir peranti mengembalikan device_code berentropi tinggi, user code pendek, URI pengesahan, tamat tempoh dan selang pengundian minimum; pelayan menyimpan kod yang dicincang dan status eksplisit. Pengguna log masuk pada telefon, menyemak klien, skop dan maklumat peranti, lalu meluluskannya. Titik akhir token hanya menerima device code: teruskan pada authorization_pending, tambah sekurang-kurangnya 5 saat pada slow_down, dan tamatkan pada tamat tempoh, penolakan atau ketidaksahan kekal. Guna kod secara atomik supaya pengundian serentak tidak boleh mengeluarkan dua set token. Layan peranti sebagai klien awam, minimumkan skop, putar token muat semula, hadkan tekaan dan minta pengguna membandingkan kod pada kedua-dua skrin. Metrik dan ujian merangkumi pengikatan aliran, backoff, pemulihan dan sempadan pancingan data.
Kesilapan lazim
- Menganggap device code sebagai kod yang dimasukkan manusia dan mendedahkan kelayakan bernilai tinggi dalam UI atau log.
- Mengabaikan
slow_downdan melakukan pengundian titik akhir token pada kadar tinggi yang tetap. - Mencuba semula setiap ralat, termasuk tamat tempoh dan penolakan, selama-lamanya.
- Berpura-pura bahawa rahsia peranti statik menjadikan klien awam sebagai sulit.
- Menghantar token akses terus melalui URL pelayar atau skrip halaman selepas kelulusan.
- Gagal menggunakan device code secara atomik dan mengeluarkan beberapa token muat semula.
- Menguji titik akhir pengundian secara berasingan tanpa membuktikan peranti yang diluluskan sepadan dengan sesi token.
Soalan susulan
Bagaimanakah anda memilih panjang dan jangka hayat user code?
Imbangkan kemudahan kemasukan, kos tekaan dalam talian dan masa penyempurnaan. Elakkan aksara yang mengelirukan, hadkan percubaan gagal dan kadar agregat, serta jadikan jangka hayat cukup panjang untuk pengguna mengambil telefon, log masuk dan mengesahkan peranti tanpa mencipta tetingkap pancingan data tanpa had. Kalibrasi nombor mengikut model ancaman dan masa penyempurnaan yang diperhatikan.
Bagaimanakah anda menghalang klien berniat jahat daripada memenuhi semua sesi?
Hadkan kadar penciptaan mengikut pendaftaran klien, IP, cap jari peranti dan akaun; hadkan sesi yang belum selesai bagi setiap prinsipal dan bersihkan sesi yang telah tamat tempoh secara tak segerak. Sahkan klien dan skop sebelum mencipta sesi. Jangan pindahkan tekanan pembersihan sampah device code ke titik akhir token.
Bagaimanakah peranti luar talian pulih selepas kelulusan?
Kekalkan sesi sehingga tamat tempoh supaya peranti boleh melakukan pengundian dengan kod yang sama selepas menyambung semula. Kembalikan sama ada set token atau keadaan terminal. Jadikan pengendalian penebusan bersifat idempoten supaya respons yang hilang tidak menyebabkan penggunaan kali kedua. Selepas tamat tempoh, mulakan semula dengan kod baharu dan maklumkan pengguna.
Apakah risiko verification_uri_complete?
Meletakkan user code dalam pautan mengurangkan penaipan tetapi meningkatkan risiko kebocoran pautan dan pancingan data jarak jauh. Tetap paparkan kod pendek dan minta pengguna membandingkannya dengan skrin peranti. Jangan dedahkan pautan lengkap kepada analitik, pengepala Referer, sejarah atau pengalihan pihak ketiga. Tawarkannya hanya apabila keupayaan peranti dan model ancaman membenarkannya.
Mengapa tidak memindahkan token akses dari telefon ke peranti?
Pemindahan token merentas peranti meluaskan pendedahan melalui pelayar, kod QR, papan keratan dan halaman perantara, serta sukar untuk membuktikan bahawa penerima ialah peranti yang betul. Device Flow membolehkan peranti menebus kodnya sendiri melalui TLS; halaman pengguna hanya mengubah keadaan pelayan. Tambahkan saluran medan dekat (near-field) yang disahkan secara berasingan jika produk memerlukannya.
Bagaimanakah anda mengesahkan bahawa pengundian melakukan backoff dengan betul?
Rekodkan bilangan pengundian peringkat sesi, taburan selang, selang sebenar selepas slow_down, kependaman terminal dan kegagalan agregat klien. Suntik pengundian berulang dalam ujian terkawal dan sahkan bahawa slow_down meningkatkan selang klien sekurang-kurangnya 5 saat tanpa ribut tersinkron. Asingkan klien yang menyalahgunakan daripada melonggarkan selang global.