DNS Rebinding Mengubah Validasi Nama Menjadi Risiko Saat Koneksi Dibuka
Fitur HTTP outbound dapat terlihat aman setelah menolak alamat IP loopback dan private yang ditulis secara langsung. Service mem-parsing URL dari user, me-resolve hostname, memeriksa alamat hasil resolusi terhadap allowlist, lalu membiarkan HTTP client membuka koneksi.
Urutan tersebut memiliki celah. Keputusan policy berlaku pada alamat yang terlihat pada satu waktu, sedangkan koneksi jaringan dapat melakukan lookup DNS lain beberapa saat kemudian. Jika hostname dikendalikan attacker, jawaban DNS dapat berubah di antara kedua tahap itu. Nama yang sudah divalidasi tetap sama, tetapi alamat tujuan berubah.
Pola ini umum disebut DNS rebinding. Pada pengambilan URL di sisi server, kondisi tersebut mengubah pemeriksaan hostname menjadi masalah time-of-check/time-of-use. Boundary yang kuat memvalidasi alamat yang benar-benar dipakai socket, bukan sekadar jawaban sebelumnya untuk nama yang sama.
Hostname bukan tujuan jaringan yang tetap
DNS memetakan nama ke record dengan masa cache, bukan menetapkan satu alamat permanen untuk setiap hostname. Data authoritative dapat berubah, cache dapat kedaluwarsa, dan satu nama dapat secara sah mengembalikan beberapa alamat.
Fleksibilitas itu merupakan perilaku DNS normal. Risikonya muncul ketika aplikasi memperlakukan lookup sebelumnya sebagai bukti bahwa koneksi berikutnya akan menuju alamat yang sama.
Perhatikan urutan berikut:
1. input: https://asset.example.invalid/file
2. validator me-resolve hostname
asset.example.invalid -> 203.0.113.40
3. policy menerima alamat tersebut
4. HTTP client me-resolve hostname lagi
asset.example.invalid -> 127.0.0.1
5. client terhubung ke 127.0.0.1Alamat pada contoh hanya ilustrasi. Defect-nya berada pada keputusan yang terpisah: satu alamat diberi izin, tetapi alamat lain yang dipakai.
TTL DNS yang pendek dapat membuat perubahan jawaban terjadi cepat, tetapi TTL bukan properti keamanan utama. Walaupun ada caching, komponen aplikasi dapat memakai resolver, cache, atau logika pemilihan alamat yang berbeda. Policy tidak boleh mengasumsikan dua resolusi independen selalu menghasilkan tujuan yang sama.
Parsing URL dan resolusi DNS adalah boundary terpisah
Validator URL lebih dulu harus menetapkan host yang akan diinterpretasikan client. Pemeriksaan string bukan pengganti URL parser yang mengikuti sintaks yang sesuai karena host dapat mencakup IPv4, IPv6, literal IPv6 dalam kurung siku, nama, port, user information, dan aturan normalisasi.
Setelah parsing, literal IP dapat langsung diklasifikasikan. Hostname memerlukan resolusi sebelum policy tujuan berbasis IP dapat diterapkan.
Pipeline yang berguna berbentuk:
URL mentah
|
v
parse dengan satu model URL
|
v
ambil scheme, host, port
|
+---- literal IP ----> klasifikasi alamat
|
+---- hostname ------> resolve
|
v
klasifikasi semua kandidat
|
v
konek hanya ke IP yang diterimaSemantik parser yang sama sebaiknya dipakai untuk validasi dan pembukaan koneksi. Jika validator menafsirkan satu host sedangkan HTTP library menafsirkan host lain, pinning DNS tidak dapat memperbaiki mismatch tersebut.
Klasifikasi harus mencakup address space yang memang dibatasi policy
Rule yang hanya menolak 127.0.0.1 lebih sempit daripada rule yang menolak seluruh tujuan loopback. Demikian pula, menolak range private IPv4 RFC 1918 tidak mencakup IPv6 loopback, alamat link-local, atau range lain yang dianggap internal maupun special-purpose oleh deployment.
Deny policy yang tepat bergantung pada service. Fetcher khusus internet biasanya perlu mengecualikan tujuan yang tidak boleh dicapai melalui input tidak tepercaya, termasuk range lokal, private, link-local, dan infrastruktur khusus deployment. Service yang memang perlu menjangkau sistem internal memerlukan model berbeda, biasanya allowlist tujuan eksplisit, bukan policy internet yang luas.
Klasifikasi sebaiknya bekerja pada alamat biner yang sudah di-parse jika memungkinkan. Bentuk teks dapat memiliki beberapa representasi valid, terutama pada IPv6. Mengubah alamat ke tipe address canonical milik networking library mencegah security policy bergantung pada pola string buatan sendiri.
Bentuk IPv4-mapped IPv6 juga perlu ditangani secara eksplisit. Classifier harus menerapkan policy IPv4 yang dimaksud setelah normalisasi, bukan membiarkan representasi dari address family lain melewati rule.
Setiap alamat kandidat memerlukan keputusan policy
Jawaban DNS dapat berisi beberapa record A atau AAAA. Memeriksa satu alamat yang diterima lalu menyerahkan hostname kembali kepada client tidak cukup karena client dapat memilih kandidat lain.
Untuk policy internet-only, rule konservatif dapat menolak hostname jika ada kandidat yang berada di luar himpunan tujuan yang diizinkan. Desain lain dapat mempertahankan hanya kandidat yang diterima dan membatasi connection attempt ke himpunan yang sudah difilter. Pilihannya bergantung pada kebutuhan availability, tetapi koneksi tidak boleh diam-diam memperoleh kembali akses ke kandidat yang ditolak.
Pemilihan alamat juga dapat berubah seiring waktu. Logika koneksi bergaya Happy Eyeballs dapat menjalankan kandidat IPv6 dan IPv4 secara bersamaan. Mekanisme itu berguna untuk latency, tetapi setiap kandidat yang dapat memenangkan race harus memenuhi destination policy yang sama.
Invariant berlaku pada seluruh koneksi yang mungkin terjadi, bukan hanya record pertama dari resolver.
Ikat alamat yang disetujui ke koneksi socket
Perbaikan paling kuat menghilangkan lookup kedua yang tidak dibatasi. Resolve hostname, terapkan policy ke alamat hasil resolusi, pilih alamat yang diterima, lalu hubungkan socket langsung ke alamat tersebut.
Hostname asli tetap penting bagi application protocol. Untuk HTTPS, TLS client biasanya memerlukan hostname yang diminta untuk Server Name Indication (SNI) dan verifikasi hostname sertifikat. Pada HTTP, request authority atau field Host juga merepresentasikan origin logis.
Hasilnya adalah dua nilai berbeda:
logical host: api.example.com
socket peer: 203.0.113.25Socket terhubung ke alamat IP yang telah disetujui. Verifikasi TLS tetap memastikan sertifikat server valid untuk api.example.com, bukan untuk alamat numerik socket, kecuali aplikasi memang menggunakan URL dengan literal IP.
Pemisahan ini mempertahankan pemeriksaan identitas HTTPS normal sekaligus mencegah transport me-resolve hostname lagi di luar keputusan policy.
Redirect menghasilkan keputusan tujuan baru
HTTP redirect dapat memindahkan request ke scheme, hostname, port, atau alamat yang berbeda. Memvalidasi hanya URL awal menyisakan jalur kedua untuk melewati outbound policy.
Setiap target redirect perlu melewati pemeriksaan parsing, scheme, port, DNS, dan alamat yang sama sebelum koneksi berikutnya dibuka. Penanganan redirect otomatis memang praktis, tetapi fetcher yang sensitif terhadap keamanan biasanya memerlukan redirect hook atau loop redirect eksplisit agar policy berjalan sebelum setiap hop.
Redirect juga dapat menunjuk kembali ke hostname yang sama setelah state DNS berubah. Izin terhadap hostname awal karena itu tidak cukup. Setiap koneksi baru memerlukan alamat yang diikat ke keputusan policy untuk koneksi tersebut.
Batas jumlah redirect tetap berguna secara terpisah. Batas itu menahan loop dan membatasi pekerjaan, tetapi tidak menggantikan validasi tujuan.
Desain DNS cache tidak menggantikan pengikatan koneksi
Melakukan pinning hostname di cache aplikasi selama periode tertentu dapat mengurangi resolusi berulang, tetapi durasi cache bukan security boundary yang lengkap. Process berbeda mungkin tidak berbagi cache, kegagalan dapat memicu resolusi baru, dan perilaku library dapat melewati state pada level aplikasi.
Cache resolver lokal juga tidak dapat membuktikan bahwa HTTP client memakai jawaban yang persis sama dengan yang diperiksa validator kecuali jalur koneksi memang terikat pada hasil tersebut.
Caching tetap dapat menjadi bagian desain. Mekanisme itu dapat mengurangi traffic DNS dan memberi pemilihan alamat yang stabil selama interval terbatas. Security invariant lebih sederhana jika dinyatakan pada tahap dial: setiap socket peer harus berasal dari himpunan yang disetujui untuk connection attempt tersebut.
Proxy memindahkan titik enforcement
Jika aplikasi mengirim request outbound melalui HTTP atau SOCKS proxy, aplikasi mungkin tidak melakukan lookup DNS atau koneksi TCP terakhir. Proxy dapat menerima hostname dan me-resolve nama itu dari konteks jaringan lain.
Dalam arsitektur tersebut, memvalidasi alamat secara lokal tidak mengikat tujuan yang dipilih proxy. Enforcement point harus berpindah ke komponen yang memilih peer sebenarnya, atau protocol antara aplikasi dan proxy harus membawa bentuk tujuan yang mempertahankan alamat yang sudah disetujui sambil tetap membawa metadata logical hostname yang dibutuhkan.
Hal yang sama berlaku pada service mesh dan egress gateway. Egress terpusat dapat menjadi control point yang kuat, tetapi hanya jika policy-nya melihat informasi tujuan yang diperlukan untuk menerapkan boundary yang sama.
Connection reuse harus mempertahankan invariant yang sama
HTTP connection pool menambah kasus lain: request dapat memakai ulang koneksi yang sudah ada tanpa resolusi DNS baru.
Reuse aman hanya jika pooled connection terkait dengan origin dan peer yang diizinkan oleh policy saat ini. Perubahan policy, rule khusus tenant, atau credential dengan network scope berbeda dapat membuat pool global tidak sesuai.
Pertanyaan utamanya tetap konkret: peer mana yang akan membawa request ini, dan apakah peer tersebut sudah diberi izin berdasarkan policy yang berlaku untuk request ini?
Destination policy berada di dial boundary
DNS rebinding sulit ditahan hanya dengan rule sintaks hostname karena risikonya bersifat temporal. Sebuah nama dapat diterima pada satu lookup lalu menunjuk ke tempat lain pada lookup berikutnya.
Outbound policy yang tahan terhadap perubahan menyatukan parsing URL, resolusi DNS, klasifikasi alamat, penanganan redirect, perilaku proxy, dan pembukaan koneksi dalam satu security model. Tahap penentunya adalah mengikat alamat yang disetujui ke socket yang membawa request.
Dengan begitu, pernyataan rapuh — “hostname ini sebelumnya mengarah ke alamat yang diizinkan” — berubah menjadi invariant yang lebih kuat: “koneksi ini hanya dapat dibuka ke alamat yang lolos policy untuk attempt ini.”
Referensi
- RFC 1034, Domain Names - Concepts and Facilities: https://www.rfc-editor.org/rfc/rfc1034
- RFC 1035, Domain Names - Implementation and Specification: https://www.rfc-editor.org/rfc/rfc1035
- OWASP, Server-Side Request Forgery Prevention Cheat Sheet: https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html