Pertanyaan dan konteks
Sebuah layanan HTTP Go ditingkatkan dari 1.25 ke 1.26 dan menemukan bahwa nilai historis http://localhost:80:80/ dan http://::1/ sekarang gagal, sementara http://[::1]/ masih berhasil. Jelaskan perubahan net/url.Parse, pengaruhnya terhadap proksi dan pertahanan SSRF, serta migrasi yang tidak bergantung pada switch kompatibilitas permanen.
Go 1.26 secara default mengatur urlstrictcolons menjadi 1, menolak titik dua tambahan dalam subkomponen host yang tidak dapat ditafsirkan sebagai host:port; perilaku ini telah di-backport ke Go 1.25.2 dan 1.24.8. RFC 3986 mendefinisikan host sebagai IP-literal, alamat IPv4, atau nama terdaftar, dengan port yang dipisahkan oleh satu titik dua, sehingga IPv6 tekstual harus berada di dalam tanda kurung siku.
Yang diuji oleh pewawancara
- Bisakah Anda menjelaskan dari sintaks URI mengapa titik dua tambahan bersifat ambigu atau tidak valid?
- Bisakah Anda membedakan IPv6 tanpa tanda kurung siku,
[IPv6]:portyang valid, hostname, dan port yang tidak valid? - Bisakah Anda menangani migrasi konfigurasi, URL pihak ketiga, penulisan ulang proksi (proxy rewriting), dan log alih-alih menonaktifkan validasi?
- Bisakah Anda menjelaskan bahwa
GODEBUG=urlstrictcolons=0adalah alat kompatibilitas sementara, bukan kebijakan validasi input? - Bisakah Anda membuktikan perilaku penguraian, koneksi, pengalihan (redirect), dan SSRF dengan uji regresi setelah peningkatan?
Pertanyaan untuk diklarifikasi terlebih dahulu
- Apakah URL yang gagal berasal dari konfigurasi manusia, basis data, input pengguna, atau callback pihak ketiga? Tingkat kepercayaan mereka berbeda.
- Apakah aplikasi menggabungkan
url.Parse,url.Hostname, danurl.Port? API penguraian yang berbeda mengubah perilaku. - Apakah IPv6 internal harus didukung, apakah port diperlukan, dan bisakah proksi menulis ulang Host?
- Bisakah nilai lama diperbaiki secara online, atau bisakah nilai tersebut divalidasi dan ditolak dalam batch pra-rilis?
- Apakah layanan menggunakan penguraian URL untuk kontrol akses, perutean tenant, atau pertahanan SSRF?
Jawaban 30 detik
"Saya akan mengklasifikasikan kegagalan berdasarkan sumber dan bentuk host. Go 1.26 mengaktifkan urlstrictcolons secara default, sehingga IPv6 tanpa tanda kurung siku dan string dengan beberapa titik dua pada host akan ditolak; bentuk eksplisitnya adalah [::1], dengan port yang ditulis sebagai [::1]:8080. Saya akan memperbaiki dan menolak nilai buruk di batas konfigurasi, menambahkan uji regresi penguraian dan jaringan, serta memantau tingkat kegagalan dalam canary. GODEBUG=urlstrictcolons=0 hanya merupakan alat rollback dan pembersihan jangka pendek, tidak pernah menjadi kebijakan permanen untuk input yang tidak tepercaya."
Pembahasan mendalam langkah demi langkah
- Tetapkan baseline. Kumpulkan sampel yang gagal pada versi lama dan Go 1.26, catat kesalahan penguraian, nilai mentah, sumber, dan penggunaan akhirnya. "Berhasil diurai" bukan berarti "aman untuk dikoneksikan"; periksa juga skema, hostname, port, dan pengalihan.
- Klasifikasikan berdasarkan sintaks URI.
http://[::1]/adalah IP-literal dalam tanda kurung siku;http://[::1]:8080/menempatkan port setelah tanda kurung siku.http://::1/menggunakan titik dua baik sebagai data host maupun pemisah port, sementarahttp://localhost:80:80/berisi beberapa pemisah port; keduanya merupakan nilai yang harus diperbaiki.
- Perbaiki batasan data terlebih dahulu. Tambahkan validasi ke file konfigurasi, migrasi basis data, dan API admin: normalisasikan IPv6 dengan tanda kurung siku, urai port sebagai bilangan bulat dalam rentang yang valid, dan tolak host yang tidak dapat ditafsirkan. Selama pembersihan batch, pertahankan nilai asli, nilai yang dikoreksi, dan sumber pemiliknya; isolasi data yang tidak dapat diputuskan secara otomatis.
- Tinjau jalur keamanan. Kontrol akses harus menggunakan
Hostname(), port, dan hasil IP yang telah diurai, dengan batasan eksplisit untuk DNS, pengalihan, dan penulisan ulang proksi. Jangan pernah mengklasifikasikan tujuan internal versus publik dari prefiks string atau satu hasilParse. Jalankan kembali kasus uji SSRF, proksi, dan pengalihan setelah peningkatan.
- Rancang rollback sementara.
GODEBUG=urlstrictcolons=0dapat memulihkan perilaku lama dalam lingkungan terkendali, tetapi memerlukan masa kedaluwarsa, metrik, dan peringatan, serta tidak boleh membiarkan input pengguna baru melewati validasi. Opsi yang lebih aman adalah mengaktifkannya hanya untuk kumpulan konfigurasi lama yang telah diinventarisasi dalam proses terisolasi, lalu menonaktifkannya setelah pembersihan selesai.
- Canary dan verifikasi. Jalankan shadow traffic dan sekumpulan kecil instans, bandingkan kesalahan penguraian, kesalahan koneksi, kecocokan proksi, dan hasil pengalihan. Pintu pemeriksaan (gates) harus mencakup IPv4 yang valid, IPv6 dalam tanda kurung siku, IPv6 yang buruk, titik dua tambahan, port kosong, dan pengalihan berbahaya. Lakukan ekspansi hanya setelah pembersihan konfigurasi lama selesai.
func validateEndpoint(raw string) (*url.URL, error) {
u, err := url.Parse(raw)
if err != nil {
return nil, err
}
if u.Scheme != "http" && u.Scheme != "https" {
return nil, fmt.Errorf("unsupported scheme")
}
host := u.Hostname()
if host == "" {
return nil, fmt.Errorf("missing host")
}
if p := u.Port(); p != "" {
n, err := strconv.Atoi(p)
if err != nil || n < 1 || n > 65535 {
return nil, fmt.Errorf("invalid port")
}
}
return u, nil
}Jawaban model
Pertama, saya akan mengidentifikasi sumber dari setiap nilai buruk dan memisahkan kesalahan sintaks dari kegagalan koneksi. Go 1.26 memberlakukan urlstrictcolons=1 secara default, menolak http://::1/ dan http://localhost:80:80/ karena titik dua tersebut tidak dapat ditafsirkan secara tidak ambigu sebagai IPv6 yang valid atau satu port; http://[::1]:8080/ bersifat eksplisit.
Pada batasan konfigurasi dan admin, saya akan menolak nilai yang salah bentuk, secara otomatis memperbaiki data yang terbukti sebagai IPv6, dan mengisolasi data yang ambigu untuk ditinjau oleh pemiliknya. Setiap jalur yang menggunakan URL untuk perutean, proksi, atau pertahanan SSRF harus menguji ulang hostname, port, DNS, pengalihan, dan penulisan ulang proksi. GODEBUG=urlstrictcolons=0 adalah rollback kompatibilitas dengan batas waktu yang dilengkapi metrik dan peringatan, bukan cara untuk membiarkan input tidak tepercaya melewati pemeriksaan baru. Canary membandingkan kesalahan penguraian, kesalahan koneksi, dan kasus keamanan sebelum rollback dihapus.
Kesalahan umum
- Gejala: Memperlakukan setiap string IPv6 tanpa tanda kurung siku sebagai valid → Penyebab kegagalan: Batas host dan port menjadi ambigu → Solusi: Gunakan
[IPv6]dan letakkan port setelah]. - Gejala: Mengatur
GODEBUG=urlstrictcolons=0secara permanen → Penyebab kegagalan: Input buruk dan ambiguitas bawaan tetap ada → Solusi: Tetapkan masa kedaluwarsa serta perbaiki data dan batas validasi terlebih dahulu. - Gejala: Hanya menguji apakah
url.Parsemengembalikan error → Penyebab kegagalan: Hostname, port, DNS, pengalihan, dan proksi dapat mengubah hasil keamanan → Solusi: Uji seluruh jalur jaringan secara menyeluruh. - Gejala: Mengklasifikasikan alamat privat dari string mentah → Penyebab kegagalan: Encoding, penguraian, DNS, dan pengalihan dapat melewati aturan berbasis string → Solusi: Urai secara konsisten, lakukan resolusi IP, dan terapkan kembali kebijakan setelah setiap pengalihan.
Pertanyaan lanjutan dan respons
Konfigurasi lama harus dipulihkan hari ini. Bagaimana Anda mengendalikan risikonya?
Aktifkan urlstrictcolons=0 hanya untuk proses yang terisolasi atau kumpulan konfigurasi lama yang diinventarisasi secara eksplisit, dengan masa kedaluwarsa, pembatasan sumber dan target, serta metrik untuk setiap penggunaan. Nilai baru tetap menggunakan validasi ketat; tutup rollback setelah pembersihan selesai.
Mengapa [::1] valid sementara ::1 tidak disarankan?
URI authority menggunakan titik dua untuk memisahkan host dan port. Tanda kurung siku memperjelas batas antara IP-literal IPv6 dan port. Menempatkan ::1 secara langsung dalam hostport bersifat ambigu, sehingga Go 1.26 menolaknya.
Di mana proksi harus melakukan validasi ulang?
Penguraian pada ingress saja tidak cukup. Setelah menulis ulang Host, mengikuti pengalihan, atau melakukan resolusi DNS ulang, terapkan kembali kebijakan skema, hostname, IP, port, dan jaringan ke tujuan baru; jangan membawa keputusan URL awal melintasi hop berikutnya.
Bagaimana Anda menunjukkan bahwa peningkatan ini tidak memperluas penolakan yang tidak semestinya?
Pertahankan korpus pengujian tetap yang berisi IPv4 valid, IPv6 dalam tanda kurung siku, URL dengan port, host yang salah bentuk dengan titik dua ekstra, host kosong, port tidak valid, dan pengalihan. Jalankan korpus tersebut pada Go 1.24.8, 1.25.2, dan 1.26, lalu bandingkan tingkat kegagalan konfigurasi nyata selama canary.
Referensi
- Catatan Rilis Go 1.26
- Go, Kompatibilitas Mundur, dan GODEBUG
- RFC 3986 Sintaks Generik Pengidentifikasi Sumber Daya Seragam (URI)
- Kode sumber Go
net/url
Daftar periksa wawancara
Jelaskan host, tanda kurung siku IPv6, dan batas port terlebih dahulu. Kemudian bahas pembersihan data, validasi batas yang ketat, pengujian ulang jalur SSRF, dan rollback GODEBUG yang memiliki masa kedaluwarsa. Pisahkan kompatibilitas penguraian dari keamanan akses.
Kesimpulan satu kalimat
Go 1.26 mengharuskan layanan untuk mengubah URL ambigu menjadi URI eksplisit serta menggunakan pengujian, canary, dan rollback berbatas waktu untuk migrasi yang aman.