Kerentanan Nginx yang Membocorkan Vault Bitwarden
(labs.hakaioffsec.com)- Nginx, server web serbaguna dengan pangsa pasar dominan sejak 2004
- Konfigurasi Nginx yang keliru dapat menyebabkan kerentanan keamanan dan kebocoran data
- Memperkenalkan NavGix, alat otomatis untuk mendeteksi kerentanan pada Nginx
- Kerentanan ini dapat memungkinkan akses ke file dan direktori di luar cakupan yang dimaksud
- Studi kasus terhadap Bitwarden dan HPC Toolkit milik Google menunjukkan tingkat keparahan kerentanan ini
1 komentar
Komentar Hacker News
Sebagai referensi, gixy (pemeriksa konfigurasi nginx) memang mendeteksi masalah ini: https://github.com/yandex/gixy/blob/master/docs/en/plugins/a...
Dan NixOS secara otomatis menjalankan gixy pada konfigurasi yang dihasilkan olehnya, lalu menolak build sistem jika ada masalah
$uripada redirect 301Tapi saya penasaran apakah ada pencari opsi yang lebih baik. Saya kurang suka harus mencari di seluruh ribuan opsi; saya ingin melihat hanya paket seperti
sshdan opsi yang sesuai dengannya, tapi terlalu banyak hasil yang tidak relevan ikut munculMungkin ini pertanyaan bodoh, tapi adakah alasan bagus nginx harus mengizinkan naik ke direktori induk dengan
..di path URL? Ini cuma terlihat seperti perilaku yang menunggu masalahEdit: Saya agak bingung tentang apa yang sebenarnya terjadi pada kerentanan aslinya. Sepertinya http://localhost/foo../secretfile.txt ditafsirkan seperti
/var/www/foo/../secretfile.txt, tetapi pada server yang tidak rentan, kenapa http://localhost/foo/../secretfile.txt tidak ditafsirkan dengan cara yang sama? Saya tidak paham kenapa..di dalam path hanya bekerja pada kondisi tertentuDalam kasus ini, sebagian URL ditafsirkan sebagai direktori oleh nginx (http://localhost/foo) karena cara pemetaannya ke filesystem lokal di konfigurasi. Karena itu tampak menunjuk ke direktori, saat nginx membangun path lengkap untuk resource yang diminta, hasilnya menjadi
"${mapped_path}/../secretfile.txt", dan meskipun itu tidak masuk akal dari sudut pandang URL, itu tetap valid di filesystem lokal. URL hanyalah string, bukan elemen path nyata, jadi posisi slash pada dasarnya tidak pentingIni adalah masalah yang sangat umum di web server secara umum sejak web pertama kali muncul. Pemetaan URL langsung ke path file populer karena berawal dari file server sederhana dengan indeks, tetapi segera berubah menjadi lingkungan campuran di mana URL bukan lagi path, melainkan pengenal aplikasi. Sebagian path dipakai untuk menunjuk aplikasi, dan sisanya dianggap parameter atau argumen
Dan secara umum, menghormati
.atau..dari URL untuk objek filesystem biasanya tidak masuk akal. Aplikasi saya merapikan path request agar dipetakan dengan benar. Browser memperlakukan URL seperti path saat membuat tautan relatif, jadi penggunaan trailing/juga harus diperhatikan dengan hati-hati. Di sisi server, itu bisa menunjuk ke resource dengan makna yang berbedaallow_parent_traversal on;dilocation, dan itu menjadi perilaku yang harus diaktifkan secara eksplisit"/foo/bar/.."lalu melarangnya atau menormalkannya menjadi"/foo/". Tetapi"/foo/bar.."adalah nama file yang sepenuhnya valid, jadi tampaknya lolos dari pemeriksaan semacam itu..bekerja dalam suatu path sepenuhnya bergantung pada izin fileDalam kasus ini, andaikan dari direktori indeks web (
../index.html) ada izin untuk membaca file hingga ke direktori root (/), maka karena kita bisa naik sampai root, kita sekarang juga bisa melihat semua file yang world-readable dan dapat diakses dari root, misalnya/etc/passwdBayangkan garpu bercabang tiga, dengan web server berada di cabang paling kanan. Jika bagian gagang tempat cabang-cabang itu bertemu adalah filesystem, maka ketika web server punya izin mengakses file dan direktori dari cabang kanan hingga ke gagang, setelah mencapai gagang itu ia bisa terus mengakses file di cabang-cabang lain juga
Saya tidak mengerti kenapa ini tidak dianggap sebagai kerentanan nginx. Perilaku ini benar-benar absurd, tampaknya tidak punya tujuan yang berguna, dan bisa langsung dieksploitasi
Perlu diingat juga bahwa Nginx menjadi populer berkat benchmark yang menunjukkan bahwa ia lebih “web scale” daripada Apache2
Ada pemikiran seperti ini: menambahkan opsi mirip Linux capability yang menghapus opsi
..dari parser nama file di kernel Linux.Di aplikasi web, sejak zaman masih memakai modem telepon, berbagai cara bypass untuk menyisipkan dua titik terus bermunculan. Seperti halnya kernel Linux menangani berbagai kategori bug ruang pengguna lainnya, mungkin sudah waktunya mencari cara untuk menutup masalah ini sekaligus
RESOLVE_BENEATHdi https://man7.org/linux/man-pages/man2/openat2.2.htmlFreeBSD punya fungsi ini di
openat(2)biasa lewatO_RESOLVE_BENEATHCukup jalankan nginx sebagai pengguna terpisah dengan hak yang sangat terbatas, atau jalankan di Docker. Ditambah pembaruan rutin, biasanya 90% masalah keamanan sudah teratasi
/some/../pathhampir 100% seharusnya dilarang. Tidak ada use case yang masuk akal selain “seseorang menulis kode yang jelek dilihat”../some/pathsetidaknya kadang memang punya artiMeski begitu, sepertinya tidak akan seguna yang dibayangkan. Banyak aplikasi sudah lebih dulu mengurai
..sebelum menyerahkannya ke sistem operasiJika Anda menyajikan file dari folder ke web, framework web harus memastikan tidak keluar dari folder root publik yang menjadi tanggung jawabnya. Jika membuatnya sendiri, Anda harus mempertimbangkan segala macam situasi termasuk hal seperti ini
“Google VRP Team memberi hadiah 500 dolar atas penemuan kerentanan ini. Mereka menilai dampaknya pada aplikasi tidak cukup serius untuk mendapat hadiah yang lebih besar”, jadi email akun GCP dan kunci privat yang terekspos cuma dihargai 500 dolar? Apa-apaan ini. Sangat Google sekali
Untungnya hal-hal yang bocor masih tetap terenkripsi. Bahkan perusahaan yang memang bergerak di bidang ini pun tidak kebal terhadap kebocoran, jadi sejujurnya ini skenario terbaik yang bisa diharapkan
Judulnya sudah cukup banyak diedit. Judul aslinya adalah Hunting for Nginx Alias Traversals in the wild
Judul kiriman HN menonjolkan kerentanan Bitwarden, tetapi di dalam tulisannya kasus Google juga dibahas
Jika yang dibutuhkan hanya penyajian file statis yang aman secara konsisten dengan penggunaan resource seminimal mungkin, apa pilihan terbaik saat ini? Dulu saya pasti akan memilih Nginx, tetapi dari sudut pandang keamanan saya penasaran apakah alat yang lebih sempit tujuannya dan lebih sedikit kemungkinan konfigurasinya akan lebih baik
Lintas platform, ditulis dengan Rust, konfigurasinya sederhana, dan punya default yang aman. Ada juga image container yang diperkeras dan modul NixOS yang diperkeras
Saya tidak merekomendasikan Caddy. Image Docker resminya secara default berjalan sebagai root [1], dan juga tidak menyediakan unit file systemd yang benar-benar tersandbox dengan baik [2]
[1]: https://github.com/caddyserver/caddy-docker/issues/104
[2]: https://github.com/caddyserver/dist/blob/master/init/caddy.s...
Edit: merapikan ungkapan
file_serveryang solidMungkin ini pertanyaan bodoh, tetapi mengapa Bitwarden sejak awal mengizinkan permintaan tanpa autentikasi ke
/attachments? Bukankah kalau URL itu tetap memerlukan autentikasi, permintaannya akan gagal bahkan meski ada bug Nginx?Tetap saja, karena mereka mendistribusikan konfigurasi berbahaya lewat Docker, ini memang tanggung jawab Bitwarden. Sepertinya Bitwarden juga mengakui hal itu dan kemudian memperbaikinya
Maaf kalau ini pertanyaan bodoh. Bukankah dengan kepemilikan direktori dan file yang tepat, traversal seperti ini bisa dicegah?
Jika nginx tidak berjalan sebagai root, bagaimana ia bisa membaca file lain selain file yang secara eksplisit diberikan kepada pengguna nginx?
go-rwxpada semua file aplikasi, lalu setel grup file “static” kewww-datadan berikan hanyag+r, maka web server tidak akan bisa mengakses file aplikasiIni benar-benar dasar hosting aplikasi 101, dan orang-orang sudah melakukannya 20 tahun lalu
/homeMungkin perlu sedikit mengutak-atik keanggotaan grup, tapi itu sangat sepadan
Mungkin saya benar-benar sedang membuat kekacauan besar. Aduh
www-data. Jika aplikasi menghasilkan data sensitif, tentu lebih baik memakai umask 077Sayangnya nginx dan web server lain biasanya memang perlu berjalan sebagai root pada aplikasi web umum. Karena mereka harus listen di port 80 atau 443. Port di bawah 1024 hanya bisa dibuka oleh root
Penjelasan lebih lanjut ada di sini: https://unix.stackexchange.com/questions/134301/why-does-ngi...