Gawat, NextJS terancam... 13 kerentanan BARU
BBetter Stack
Computing/SoftwareBusiness NewsInternet Technology
Transcript
00:00:00Terjadi lagi. Ini seperti video ketiga saya tentang CVE komponen server tahun ini dan saya
00:00:05bahkan tidak berpikir telah membahas semuanya. Kali ini ada 13 CVE, ya 13, di seluruh React
00:00:11dan Next.js, 6 di antaranya tingkat keparahan tinggi termasuk denial of service, bypass
00:00:15middleware, cross-site scripting, dan lainnya. Mungkin komponen server adalah sebuah kesalahan.
00:00:20Jadi ini adalah rilis keamanan Next.js, Anda tahu, hanya memperbaiki beberapa masalah biasa di sini
00:00:28yang mereka alami bulan ini dan di bagian bawah tentunya solusinya adalah memperbarui
00:00:32semua versi Next.js Anda dan inilah versi yang terdampak. Perlu dicatat
00:00:36bahwa TanStack tidak terdampak oleh hal ini, saya mungkin bias tapi itu alasan lain menggunakan
00:00:41TanStack bagi saya. Sekarang saya tidak akan membahas semuanya karena kita mungkin akan lama di sini
00:00:44dan saya juga belum menemukan eksploitasi yang berfungsi untuk semuanya, tapi saya ingin menunjukkan satu
00:00:48dari setiap kategori dan kita akan mulai dengan bypass middleware dan proxy, dan yang
00:00:52berhasil saya buat ulang adalah router halaman ini. Jadi kita memiliki bypass proxy middleware di
00:00:56router halaman jika Anda menggunakan i18n dan Anda bisa melihat ini adalah CVE dengan skor
00:01:02keparahan 7,5 dari 10. Ini contoh aplikasi yang rentan, jadi di konfigurasi Next.js saya sudah
00:01:06mengaktifkan i18n dan juga mengatur dua locale yaitu Inggris dan Prancis, lalu saya juga punya file middleware
00:01:12yang sebenarnya sudah diubah namanya menjadi proxy di versi Next.js yang lebih baru untuk mencoba
00:01:16menghindari kebingungan yang akan saya tunjukkan, namun intinya apa yang seharusnya middleware izinkan
00:01:19untuk kita lakukan adalah memodifikasi permintaan masuk, baik itu dengan mengalihkan, menulis ulang,
00:01:24atau menambahkan beberapa header atau hal semacam itu. Dalam kasus saya, saya menggunakannya agar
00:01:28saat kita mencoba mengunjungi halaman /secret, ia akan memeriksa apakah mereka memiliki cookie sesi
00:01:32sehingga mereka sudah login, dan jika tidak, ia akan mengalihkan mereka ke halaman login
00:01:37jadi diharapkan hanya pengguna yang terautentikasi yang bisa melihat halaman rahasia saya.
00:01:41Di bagian bawah kita juga memiliki matcher agar middleware apa pun yang kita terapkan
00:01:45pada halaman rahasia itu juga mencocokkan varian locale-nya karena secara teknis
00:01:50sekarang karena kita punya dua locale, kita punya tiga versi URL ini. Di halaman rahasia itu sendiri
00:01:54saya juga memiliki beberapa server-side props; ini seharusnya diambil dari server pada saat rendering
00:01:58dan sekali lagi karena kita sudah mengatur middleware tersebut, secara teori hanya pengguna yang login yang bisa melihat
00:02:03apa nilai-nilai ini yang kemudian saya gunakan pada halaman itu sendiri seperti email, flag, dan
00:02:07juga headline. Sekali lagi hanya pengguna terautentikasi yang bisa melihat ini. Mari kita
00:02:11uji itu dan hal pertama yang akan saya coba adalah mengakses halaman rahasia itu dan Anda
00:02:16bisa melihat saya dialihkan ke login karena saya tidak login, yang berarti middleware kita berfungsi
00:02:20tapi bagaimana jika kita berubah menjadi peretas ahli? Kita bisa melakukannya dengan cara pertama-tama
00:02:24memeriksa elemen, hal-hal peretasan yang gila, dan kemudian di skrip data next di bawah sini kita perlu mencari
00:02:28ID build kita; dalam kasus saya adalah yang ini, dan kita bisa menyalinnya
00:02:32kemudian kita perlu mengetikkan URL yaitu underscore next slash data slash ID build yang
00:02:37baru saja kita salin dan kemudian halaman yang ingin kita akses titik JSON. Setelah itu dilakukan
00:02:40Anda bisa melihat kita mendapatkan kembali props yang seharusnya berada di balik middleware dan dilindungi
00:02:44yang dalam kasus saya adalah flag, email, headline, juga sesuatu yang menyuruh Anda berlangganan untuk
00:02:48berita pengembang, tutorial, tips, dan trik lainnya. Jadi silakan lakukan itu, saya harap saya sudah membuat Anda terkesan
00:02:52dengan keterampilan peretasan gila saya, tapi mengapa ini sebenarnya terjadi? Yah, yang ini
00:02:56sama mudahnya untuk dijelaskan seperti saat melakukannya karena kita punya halaman rahasia dan beberapa server side props,
00:03:00di Next.js server side props dilayani dari URL yang terlihat seperti ini, tetapi middleware kita
00:03:05seharusnya melindungi rute ini. Masalahnya adalah karena kita menggunakan i18n, kita juga
00:03:09memiliki dua URL lain yaitu varian Inggris dan Prancis, Anda bisa melihat bahwa server side
00:03:13props juga mendapatkan varian Inggris dan Prancis juga, dan Next.js hanya memiliki beberapa kode
00:03:18yang salah yang berarti jika kita mengaktifkan i18n, ia tidak melindungi kasus dasarnya, sehingga
00:03:22ini tidak termasuk dalam matcher tetapi dua lainnya termasuk, jadi versi Inggris dan Prancis dilindungi
00:03:26tetapi bukan kasus dasar dari slash secret. Kita bisa melihatnya dengan cepat jika saya hanya mengubah
00:03:31URL ini ke versi Inggris, saya akan dialihkan ke halaman login. Kerentanan yang sangat sederhana
00:03:35memang, tapi sejujurnya bypass middleware ini sering kali terdengar jauh lebih buruk daripada
00:03:40aslinya; ini tidak bagus tapi Anda tidak seharusnya melindungi banyak hal hanya dengan middleware saja
00:03:44dan Next.js bahkan tidak merekomendasikan Anda melakukannya. Jika Anda memiliki data sensitif
00:03:48dalam server side props tersebut dan Anda tidak memiliki logika otentikasi server, yah saya rasa
00:03:53sebagian masalahnya ada pada Anda juga, jadi mari beralih ke yang lebih merusak yaitu denial of
00:03:56service; ada tiga di antaranya tetapi hanya ada satu yang bisa saya buat ulang dengan andal dan
00:04:01itu adalah yang satu ini yaitu denial of service dengan komponen server dan ini berdampak pada Next.js
00:04:05serta apa pun yang menggunakan paket React server DOM yang pada dasarnya hanya Next.js
00:04:10dan framework lain yang menirunya seperti vinxt dan beberapa fork lainnya. TanStack
00:04:14Start tidak menggunakan ini sehingga tidak rentan. Anda bisa melihat ini juga memiliki tingkat keparahan
00:04:187,5 dari 10. Dengan yang satu ini Anda hanya butuh aplikasi Next.js yang sangat sederhana dan di
00:04:22dalamnya Anda perlu menggunakan server action tetapi sekali lagi itu bisa sangat sederhana. Ini adalah
00:04:25situsnya yang sudah berjalan dan Anda bisa melihat saat saya menyegarkan halamannya hampir
00:04:29tidak ada loading, hampir instan, dan untuk memberi angka nyata di baliknya jika saya mengirim permintaan ini
00:04:34Anda bisa melihatnya selesai dalam 0,02 detik tetapi jika sekarang saya menjalankan eksploitasi saya dan
00:04:39kemudian mengirim permintaan itu lagi, kali ini memakan waktu enam detik dan itu baru dari menjalankan eksploitasi
00:04:42sekali, jadi bayangkan apa yang terjadi jika saya merangkainya. Sekarang untuk memahami eksploitasi ini kita
00:04:46perlu tahu sedikit tentang protokol React Flight yang merupakan format yang digunakan React
00:04:50untuk menserialisasi pohon komponen dan data antara server dan klien. Anda mungkin
00:04:54sebenarnya pernah melihat ini sebelumnya; di halaman ini kita punya formulir yang memiliki server action. Jika saya
00:04:58pergi ke tab network di sini dan mengeklik send, Anda bisa melihat bahwa muatan sebenarnya dikirim
00:05:02sebagai data yang terlihat seperti ini yang tampak seperti omong kosong, dan sama juga untuk
00:05:05responsnya di sini. Jika kita menyalin muatan ini, saya bisa menjelaskan apa yang terjadi saat
00:05:10ia dikirim ke server. Langkah pertama adalah deserialisasi dan itu akan dimulai pada bongkahan 0 di mana kita punya
00:05:16$k1 ini. $k1 ini sebenarnya hanya penunjuk yang mengatakan akan ada beberapa data formulir di sini
00:05:20yang dimulai dengan satu garis bawah, jadi ia akan mengambil semua kunci lain yang kita kirimkan
00:05:24sebagai bagian dari muatan tersebut, ia akan melewati semuanya dan mencari string yang dimulai dengan
00:05:28satu garis bawah dan ia akan tahu ini akan menjadi kuncinya dan ini adalah nilainya. Jadi setelah
00:05:32itu selesai, ia bisa mengatakan kita punya nama, email, pesan, dan ia hanya akan mengubah data ini menjadi
00:05:36objek yang kita miliki di bawah sini. Bagus dan sederhana. Masalah dengan pendekatan ini
00:05:41adalah apa yang terjadi saat kita menskalakannya. Katakanlah saya menambahkan penunjuk lain, kali ini mencari $k2,
00:05:44ini akan mencari semua kunci yang dimulai dengan dua garis bawah. Masalahnya
00:05:48adalah sekarang saat kita berada di $k1, ia akan melewati keenam kunci ini mencari kunci
00:05:52yang dimulai dengan satu garis bawah, dan saat ia ke $k2, ia akan melakukan hal yang sama
00:05:56tetapi mencari kunci yang dimulai dengan dua garis bawah. Jadi kita sekarang melewati 12 kunci
00:06:03secara total. Sekarang itu tidak terlalu buruk, tapi mari kita bawa ini ke titik ekstrem. Jika kita menambahkan 199.999
00:06:07kunci acak ke muatan yang kita kirimkan dan kemudian kita mengubah array kita di nol di sini
00:06:12menjadi $k1, $k2 sampai $k1000, itu berarti ia harus mencari satu garis bawah,
00:06:17dua garis bawah, tiga garis bawah sampai seribu garis bawah di seluruh 200.000
00:06:21kunci yang kita miliki dalam muatan kita, dan itu berarti secara total ia akan melakukan 200 juta perbandingan
00:06:25string. Seperti yang bisa Anda bayangkan, itu akan memblokir thread selama beberapa detik.
00:06:28Ini adalah commit yang saya yakini memperbaiki masalah yang kita alami. Anda bisa melihat ada
00:06:33banyak hal yang terjadi dalam commit ini dan sejujurnya ini agak rumit, tapi saya akan mencoba
00:06:36menjelaskannya sebaik mungkin. Intinya sekarang mereka menggunakan sistem berbasis kursor untuk kuncinya,
00:06:41jadi mereka memuat semua 200.000 kunci yang kita kirimkan dalam muatan kita ke dalam sebuah daftar dan kemudian
00:06:45kita mulai dari nol di sini di mana ia mencari referensi $k1 dan ia mulai menyusuri
00:06:50daftar itu dengan kursor yang tidak bisa mundur. Jadi ia turun ke sini ke $j1, ia melihat itu tidak
00:06:54cocok dengan satu garis bawah yang kita butuhkan, jadi ia ke $j2, itu tidak cocok dengan satu garis bawah
00:07:01juga, jadi ia lanjut terus ke bawah daftar kunci ini sampai ke $j199.999. Setelah
00:07:06mencapai sini, ia menyadari tidak ada kecocokan untuk $k1, jadi ia lanjut ke $k2. Sekarang $k2 mulai mencari
00:07:09dua garis bawah, tapi masalahnya karena ini sistem berbasis kursor dan kursor ini
00:07:14tidak bisa mundur, ia langsung habis di ujung daftar, jadi itu juga akan
00:07:18menjadi tidak terdefinisi dan itu berlanjut sampai ke $k1000. Jadi kali ini kita hanya
00:07:23melewati 200.000 kunci. Intinya perbaikan ini telah mengurangi jumlah operasi dari
00:07:27$k*n di mana $k adalah jumlah referensi $k yang kita punya dan $n adalah jumlah kunci, menjadi
00:07:33hanya $n+k. Jadi dalam kasus kita, kita beralih dari 200.000.000 operasi menjadi 201.000 karena
00:07:37ia masih perlu menyisir semua kunci dan juga referensi $k tersebut. Saya rasa
00:07:41tweet dari Prime ini benar-benar meringkas situasi kita. Membuat protokol sendiri dengan serialisasi
00:07:46sangatlah sulit, jadi tidak mengherankan jika kita melihat banyak masalah ini. Menurut pendapat saya,
00:07:50mereka butuh Claude Mythos untuk meninjau basis kode React dan Next.js. Berikutnya,
00:07:54kita punya CVE dengan tingkat keparahan tertinggi yaitu server-side request forgery dalam
00:07:59aplikasi Next.js. Anda bisa melihat ini diberi peringkat 8,6 dari 10 tetapi perlu juga
00:08:04dicatat bahwa yang satu ini tidak berdampak pada deployment yang dihosting di Vercel, hanya yang dihosting mandiri atau penyedia lain.
00:08:09Eksploitasi ini juga sangat mudah dimanfaatkan. Pertama kita perlu menjalankan server Next.js kita
00:08:14dan sekali lagi ini bisa berupa aplikasi Next.js standar. Anda tidak perlu melakukan modifikasi apa pun.
00:08:18Selanjutnya kita juga butuh server internal. Katakanlah server ini hanya bisa diakses oleh
00:08:23server Next.js dan bukan oleh dunia luar. Katakanlah ini ada di cloud deployment kita.
00:08:26Lalu apa yang akan kita lakukan adalah mengirim permintaan curl sederhana di mana kita mengirim
00:08:31permintaan curl ke aplikasi Next.js kita. Itu tadi ada di port 3002 dan kita katakan bahwa kita ingin
00:08:36target permintaan kita adalah server yang ingin kita akses pada URL localhost tersebut. Jika saya sekarang
00:08:40menekan enter pada ini, Anda bisa melihat apa yang dikembalikan. Sebenarnya itu adalah halaman HTML untuk server Python
00:08:45di mana ia hanya memiliki daftar direktori dasar dan jika saya kembali ke server Python itu sendiri
00:08:49Anda bisa melihat bahwa ada permintaan masuk yang sebenarnya datang dari aplikasi Next.js.
00:08:53Untuk lebih membayangkan apa yang baru saja kita lakukan, katakanlah di dalam garis putus-putus ini adalah deployment Next.js kita
00:08:57jadi kita punya server Next.js dan juga beberapa layanan internal baik itu Redis,
00:09:02database, atau layanan lainnya dan layanan yang satu ini tidak ingin Anda berikan akses ke publik
00:09:06sehingga tidak ada yang bisa mengirim permintaan curl ke sini, itu hanya akan gagal, layanan itu di-firewall dan terkunci
00:09:10dan hanya bisa diakses oleh server Next.js. Apa yang kita lakukan adalah kita hanya mengirim
00:09:15permintaan curl ke server Next.js dan kita bilang hei bisakah kamu mengirim permintaan atas nama kami
00:09:19ke layanan internal dan kita mendapatkan informasi itu kembali, jadi kita sudah melewati firewall itu
00:09:23dengan melewati Next.js yang memang memiliki akses ke layanan internal. Akar penyebab
00:09:28masalah ini juga cukup sederhana, pada dasarnya dalam permintaan curl kita, kita mengirim header upgrade websocket
00:09:32dan saat kita mengirim header ini, apa yang terjadi di Next.js adalah kita sampai ke bagian
00:09:37kode ini dan ini menyelesaikan rute pada URL kita, tetapi URL yang sudah diparsing yang kita dapatkan di sini
00:09:40sebenarnya adalah target permintaan yang kita kirimkan dalam permintaan curl kita, jadi ini akan menjadi
00:09:45target yang kita coba capai di server internal tersebut dan bukan aplikasi Next.js yang sebenarnya.
00:09:49Apa yang terjadi dengan URL yang sudah diparsing ini adalah ia melewati satu pemeriksaan di bawah sini untuk menanyakan apakah
00:09:55URL tersebut punya protokol, tetapi dalam kasus ini jawabannya ya karena kita menggunakan HTTP dan itu adalah protokol
00:09:58jadi ia melanjutkan dan memproksi permintaan itu untuk kita. Perbaikan untuk ini hanya menambahkan dua
00:10:02penjaga baru pada fungsi resolve routes kita yang sebelumnya, sekarang kita mendapatkan boolean finished
00:10:06serta kode status. Apa yang sebenarnya dilakukan fungsi resolve routes ini adalah ia
00:10:11mengambil URL kita dan memproses apakah itu permintaan proksi yang sah berdasarkan rewrite Next.js kita,
00:10:15middleware, dan hal-hal semacam itu; jika tidak, itu berarti finished akan disetel
00:10:20ke false, jadi di bawah sini kita punya pemeriksaan jika finished bernilai true kita bisa lanjut ke langkah berikutnya, jika
00:10:24tidak, disetel ke false sehingga ini tidak akan berjalan yang berarti kita tidak akan menjalankan permintaan proksi kita
00:10:27dan dalam kasus permintaan curl yang kita miliki sebelumnya, itulah tepatnya yang akan
00:10:32terjadi, finished akan disetel ke false. Sekarang jika entah bagaimana finished disetel ke true, pemeriksaan
00:10:36berikutnya adalah kode status, saat resolve routes berjalan kita sebenarnya mendapatkan kode status kembali jika
00:10:41permintaan tersebut adalah permintaan HTTP, jadi kodenya akan 200, 404, apa pun itu, jadi jika ada kode status
00:10:45itu berarti itu bukan permintaan proksi web socket yang valid sehingga ia hanya akan mengabaikan
00:10:49baris ini dan tidak menjalankannya. Saya sudah benar-benar mencoba menyelami masalah ini dalam video ini
00:10:53jadi beri tahu saya jika Anda masih menonton dengan berkomentar sesuatu yang acak, entahlah seperti
00:10:58bar atau semacamnya, dan juga berlangganan jika Anda menghargai konten ini. Kita masih punya dua
00:11:01kategori lagi yang harus dibahas tapi ini harusnya sedikit lebih cepat dan saya akan mulai
00:11:04adalah cache poisoning dalam React server component dan peringkatnya 5,4 dari 10. Untuk membuat ulang
00:11:09ini saya punya aplikasi Next.js tetapi saya juga punya CDN palsu untuk bertindak seolah-olah ini ada
00:11:14di lingkungan yang benar-benar dideploy. Ini berarti jika saya mengunjungi situs saya untuk pertama kalinya pada
00:11:18URL CDN-nya dan kemudian mengeklik browse products lalu kembali dan mengekliknya lagi, pertama kali
00:11:23seharusnya terjadi cache miss dan kemudian berikutnya cache hit. Kita bisa melihat itu terjadi di log
00:11:27di sini, awalnya kita mengalami miss di slash products dengan query string dan kemudian kali berikutnya
00:11:31adalah hit. Apa yang saya lakukan selanjutnya adalah menghapus cache untuk mensimulasikan mungkin cache-nya kedaluwarsa
00:11:35atau hal lainnya dan sekarang saya bisa mengirim permintaan curl ini. Dengan itu kembali ke aplikasi saya,
00:11:39jika saya mengeklik browse products sekarang, Anda bisa melihat kita mendapatkan banyak omong kosong kembali, jadi kita sudah
00:11:44berhasil melakukan serangan cache poisoning. Apa yang saya yakini terjadi di sini adalah saat kita mengirim
00:11:47permintaan curl dengan header react-server-component bernilai satu, URL ini akan mengembalikan data server
00:11:52component-nya, bukannya HTML. Kemudian saat ini perlu di-cache, Next akan melalui
00:11:58sebuah fungsi yang memeriksa apakah itu data server component atau bukan. Jika itu data server component,
00:12:02ia akan menyimpannya dalam cache seperti itu, dan jika bukan, ia akan menyimpannya sebagai HTML. Ini berarti
00:12:07secara teori saat pengguna mencoba mendapatkan versi HTML dari halaman tersebut, misalnya dengan hanya
00:12:11mengeklik tombolnya, ia tidak akan pernah mengembalikan data server component. Masalahnya adalah dalam
00:12:16kasus kita, karena kita memiliki query string di akhir permintaan curl server component kita,
00:12:20ia tidak benar-benar memenuhi persyaratan untuk memeriksa apakah itu server component atau bukan karena
00:12:24itu hanya memeriksa apakah berakhiran .rsc, tetapi versi kita berakhiran dengan query string jadi
00:12:29sekarang ia mengira itu HTML, ia menyimpannya dalam cache sebagai HTML sehingga lain kali pengguna mengeklik
00:12:33tombol itu, mereka sebenarnya mendapatkan data server component kembali karena ia percaya
00:12:37itu adalah HTML. Perbaikan untuk yang satu ini sangatlah sederhana; saat mereka melakukan pemeriksaan apakah
00:12:41berakhiran .rsc, mereka sekarang mengabaikan query string tersebut. Sekarang beralih ke
00:12:46kategori terakhir CVE, kita punya beberapa masalah cross site scripting; ini yang berhasil saya buat ulang,
00:12:50Anda bisa melihat skornya 6,1 dari 10 dan ada cross site scripting pada
00:12:55skrip before-interactive dengan input yang tidak tepercaya. Pada dasarnya itu berarti di Next.js jika saya punya sebuah
00:12:59tag script yang memiliki strategi before-interactive, jika saya kemudian punya atribut lain pada itu yang
00:13:03membutuhkan bentuk konten yang tidak tepercaya, contohnya yang ini berasal dari search params,
00:13:08saya bisa melakukan beberapa cross site scripting, saya bisa melakukannya dengan membuat pengguna mengeklik sebuah tautan seperti
00:13:12ini contohnya, di mana saya sudah menanamkan banyak konten ke dalam search param tersebut; jika seseorang
00:13:16mengeklik tautan itu, inilah yang akan mereka lihat, jadi mereka mungkin mengira mereka harus
00:13:19login kembali ke situs tersebut dan saat mereka mengeklik sign in, Anda bisa melihat di sini bahwa itu adalah formulir
00:13:22login yang sepenuhnya palsu yang disisipkan melalui search param tersebut; ini pada dasarnya memungkinkan penyerang
00:13:26melakukan eksekusi JavaScript pada mesin korban, jadi menurut saya contoh yang lebih realistis
00:13:31adalah mencuri cookie sesi Chrome untuk login ke semua yang Anda punya aksesnya; yang satu ini
00:13:34adalah contoh sederhana dari kesalahan escaping dan kita bisa melihatnya lebih mudah dengan
00:13:39versi yang lebih sederhana ini, tetapi yang saya lakukan dalam search param itu hanyalah saya pertama-tama menutup
00:13:43tag script lalu membuka tag script baru dengan apa pun yang ingin saya jalankan; saat kita menekan
00:13:47enter pada itu Anda bisa melihat saya mendapat peringatan bertuliskan pwned seperti yang saya tunjukkan dengan aplikasi saya;
00:13:51cara kerjanya adalah kita butuh tag script Next.js yang punya strategi before-interactive
00:13:55dan Anda juga menginginkan beberapa atribut pada tag script itu yang mengambil datanya dari suatu sumber
00:13:59yang tidak tepercaya, dalam kasus saya itu berasal dari parameter query; apa yang dilakukan Next.js adalah
00:14:04tag script ini diubah menjadi sesuatu yang seperti ini di mana kita punya dangerouslySetInnerHTML,
00:14:08maksud saya dari namanya saja sudah jelas itu akan berbahaya, dan kita juga punya JSON.stringify.
00:14:12Hal penting yang perlu diketahui tentang JSON stringify adalah ia tidak meng-escape karakter HTML
00:14:17seperti kurung tutup, jadi apa yang sebenarnya terjadi di sini adalah kita mengambil semua tag script
00:14:21yang kita atur di Next.js, ia mencari sumber yang akan diatur di sini dan
00:14:24kemudian sisa propertinya akan berisi data-tracking-id serta nilai yang
00:14:29kita setel di parameter query kita, jadi itu dimasukkan ke dalam JSON stringify; apa yang sebenarnya
00:14:33dirender pada halaman adalah sesuatu seperti ini, jadi kita punya data-tracking-id yang
00:14:37merupakan sisa properti tadi, tetapi kemudian kita juga punya string yang kita masukkan melalui parameter
00:14:41query; jadi jika kita jabarkan apa yang sebenarnya terlihat pada halaman, bentuknya seperti
00:14:45ini, kita punya tag script, kita punya data-tracking-id tetapi kemudian setelah ini kita sebenarnya
00:14:49punya tag script penutup; jadi itu mengakhiri tag script yang coba dilakukan Next.js dan setelah
00:14:53ini kita bisa menjalankan skrip apa pun yang kita mau pada halaman itu, lalu kita juga punya bagian ekstra
00:14:58di akhir sini karena jika kita tidak punya ini, analitik sebenarnya akan dirender pada
00:15:01halaman sebagai teks karena HTML akan melihat ini sebagai teks; jadi bagian ini pada dasarnya hanya menelan
00:15:05teks itu sehingga tidak ada tanda-tanda jelas bahwa sesuatu yang buruk sedang terjadi di halaman itu dan akhirnya
00:15:09begitulah, itu tadi 13 CVE untuk Next.js dan React minggu ini serta bagaimana beberapa di antaranya bekerja dan sejujurnya
00:15:14saya tidak tahu harus berpikir apa tentang ini, saya membencinya dan itu datang dari seseorang yang dua
00:15:18tahunan lalu setiap proyek yang saya kerjakan ada di Next.js dan saya pikir itu adalah yang terbaik dan
00:15:22masa depan, tapi sekarang sepertinya rintangan demi rintangan; rasanya seperti mereka terburu-buru melakukan
00:15:26beberapa hal dan kemudian harus memperbaikinya nanti, secara pribadi sekarang saya benar-benar beralih ke TanStack dan juga
00:15:31Astro saat saya butuh situs berbasis konten; mereka terlihat jauh lebih sederhana bagi saya dan sejujurnya
00:15:35saya juga sangat menyukai apa yang dilakukan Cloudflare belakangan ini, jadi saya perlahan memigrasikan
00:15:39proyek-proyek saya ke sana, tapi saya masih punya sekitar 20 proyek di Vercel dan saya perlu
00:15:43memperbaruinya. Bagaimana menurut Anda, apakah komponen server akan berguna atau kita sudah mencoba dan gagal?
00:15:48Beri tahu saya di kolom komentar di bawah, jangan lupa berlangganan dan seperti biasa, sampai jumpa di
00:15:51video berikutnya.