Skip to content

Mitigasi Kerentanan SSRF pada Next.js Image Optimizer

Adityo Guni Waluyo

Konfigurasi remotePatterns wildcard menjadikan /_next/image proxy fetch terbuka. Pola penutupannya: local-only, satu host eksplisit, uji negatif.

Ringkasan

Konfigurasi Next.js KotaPortal pakai wildcard hostname plus CSP img-src https global, alhasil endpoint /_next/image bisa jadi proxy terbuka rawan SSRF. Solusinya, remotePatterns dihapus total dan CSP dipersempit, host eksternal yang emang dibutuhkan ditambahin eksplisit satu-satu. Biar nggak balik lagi, ada tes otomatis yang mastiin URL asal dikasih 400, bukan 200.

Tinjauan keamanan pada berkas konfigurasi next.config.js di proyek portal pariwisata regional KotaPortal mengungkap sebuah pola berisiko tinggi. Konfigurasi yang ditemukan menetapkan wildcard pada hostname di dalam remotePatterns, dipasangkan dengan kebijakan Content Security Policy untuk sumber gambar yang mengizinkan protokol https secara global. Kombinasi ini secara efektif mengubah endpoint bawaan /_next/image menjadi proxy pengambilan data terbuka. Endpoint tersebut menerima sembarang URL HTTPS yang dikirim melalui parameter kueri dan mengambilnya secara server-side.

Asumsi awalnya, wildcard pada hostname tetap dibatasi otomatis oleh Content Security Policy di sisi peramban. Asumsi lain, optimizer hanya memproses gambar yang dirender komponen frontend. Keduanya tidak akurat.

Dokumentasi resmi Next.js menyatakan dengan jelas bahwa menghilangkan protokol, port, pathname, atau search secara implisit mengaktifkan wildcard [1]. Praktik ini tidak direkomendasikan karena memungkinkan aktor jahat mengoptimalkan URL yang tidak dimaksudkan pengembang [2]. Aturan pencocokannya eksak dan peka huruf besar-kecil pada setiap bagian URL; host yang tidak cocok dengan pola yang diizinkan langsung merespons dengan status 400 Bad Request. Ketentuan yang sama berlaku pada dokumentasi kedua varian router [6].

Lebih jauh, OWASP mendefinisikan Server-Side Request Forgery sebagai kerentanan ketika penyerang menyalahgunakan fungsionalitas server untuk membaca atau memperbarui sumber daya internal dengan memilih URL target secara bebas [3]. Dalam konteks ini, endpoint optimizer dapat diarahkan ke layanan metadata cloud atau antarmuka HTTP internal-only yang tidak boleh terpapar ke publik.

Mengamankan Konfigurasi Image Optimizer

Langkah pertama mitigasi SSRF pada optimizer gambar adalah menghilangkan permukaan serangan yang tidak diperlukan. Seluruh aset gambar konten KotaPortal bersumber dari domain yang sama, sehingga remotePatterns dihapus sepenuhnya. Menghapus konfigurasi ini adalah keputusan desain yang disengaja. Trade-off-nya, aplikasi kehilangan fleksibilitas memuat gambar dari sumber eksternal secara dinamis. Untuk aplikasi yang aset visualnya sepenuhnya dikendalikan internal, pengorbanan tersebut sebanding dengan peningkatan postur keamanan.

Penghapusan ini memaksa optimizer hanya menerima jalur lokal. Bersamaan dengan itu, CSP img-src dipersempit agar hanya mengizinkan origin sendiri dan sumber data sah. Perubahan ini memastikan peramban hanya memuat gambar dari sumber terverifikasi, menghilangkan ketergantungan pada wildcard HTTPS yang berbahaya [4]. Prinsip least privilege diterapkan di sini: akses hanya diberikan pada sumber yang benar-benar diperlukan.

Menangani Regresi pada Autentikasi Pihak Ketiga

Setelah konfigurasi diperketat, pengujian fungsional menemukan regresi pada fitur login. Proses autentikasi Google OAuth gagal memuat foto profil pengguna. Investigasi menunjukkan URL avatar berasal dari klaim picture pada userinfo OIDC, yang berasal dari host lh3.googleusercontent.com [5].

Gambar ini dirender melalui tag img standar. Pengambilannya tidak melewati daftar pola host optimizer, tetapi tetap terikat CSP. Solusi yang tepat bukan kembali memakai wildcard, melainkan menambahkan satu host eksplisit ke kedua konfigurasi: daftar pola host optimizer dan CSP untuk sumber gambar sama-sama menerima host tersebut. Sebuah aturan komentar ditulis di berkas konfigurasi: setiap host jarak jauh baru harus ditambahkan secara eksplisit ke kedua daftar.

Validasi Perilaku Melalui Pengujian Otomatis

Konfigurasi yang aman perlu diverifikasi secara programatik untuk mencegah regresi. Sebuah pengujian end-to-end negatif dikunci untuk perilaku ini. Pengujian mengirim permintaan ke endpoint optimizer dengan payload yang meniru upaya eksploitasi standar.

curl -s -o /dev/null -w "%{http_code}" \
  "https://example.com/_next/image?url=https%3A%2F%2Fevil.example%2Fx.png&w=384&q=75"
# output yang diharapkan: 400 (atau status apa pun selain 200)

Parameter url dikirim dalam bentuk URL-encoded, seperti cara peramban atau klien HTTP mengirim parameter kueri secara umum. Jika server tidak memvalidasi URL hasil dekode secara ketat, kerentanan tetap terekspos meski tersembunyi di balik encoding. Hasil yang diharapkan adalah status selain 200 OK, idealnya 400 Bad Request. Bila pengujian mengembalikan 200, optimizer diam-diam kembali menjadi proxy terbuka. Mitigasi seperti ini hanya tahan lama bila perilakunya dikunci oleh pengujian, bukan oleh niat baik konfigurasi.

Sources

Artikel terkait