Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Catatan
Ini bukan versi terbaru dari artikel ini. Untuk rilis saat ini, lihat versi .NET 9 dari artikel ini.
Peringatan
Versi ASP.NET Core ini tidak lagi didukung. Untuk informasi selengkapnya, lihat Kebijakan Dukungan .NET dan .NET Core. Untuk rilis saat ini, lihat versi .NET 9 dari artikel ini.
Penting
Informasi ini berkaitan dengan produk pra-rilis yang mungkin dimodifikasi secara substansial sebelum dirilis secara komersial. Microsoft tidak memberikan jaminan, tersirat maupun tersurat, sehubungan dengan informasi yang diberikan di sini.
Untuk rilis saat ini, lihat versi .NET 9 dari artikel ini.
Artikel ini menjelaskan cara mengurangi ancaman keamanan di sisi Blazorserver interaktif .
Aplikasi mengadopsi model pemrosesan data stateful, di mana server dan klien mempertahankan hubungan yang tahan lama. Status persisten dipertahankan oleh sirkuit, yang dapat mencakup koneksi yang juga berpotensi berumur panjang.
Saat pengguna mengunjungi situs, server membuat sirkuit di memori server. Sirkuit menunjukkan kepada browser konten apa yang akan dirender dan merespons peristiwa, seperti ketika pengguna memilih tombol di UI. Untuk melakukan tindakan ini, sirkuit memanggil fungsi JavaScript di browser pengguna dan metode .NET di server. Interaksi berbasis JavaScript dua arah ini disebut sebagai interop JavaScript (JS interop).
Karena JS interop terjadi melalui Internet dan klien menggunakan browser jarak jauh, aplikasi berbagi sebagian besar masalah keamanan aplikasi web. Topik ini menjelaskan ancaman umum terhadap aplikasi sisi Blazor server dan menyediakan panduan mitigasi ancaman yang berfokus pada aplikasi yang terhubung ke Internet.
Di lingkungan yang dibatasi, seperti di dalam jaringan perusahaan atau intranet, beberapa panduan mitigasi:
- Tidak berlaku di lingkungan yang dibatasi.
- Tidak sepadan dengan biaya yang harus diterapkan karena risiko keamanan rendah di lingkungan yang dibatasi.
Komponen Server Interaktif dengan pemadatan WebSocket diaktifkan
Kompresi dapat mengekspos aplikasi ke serangan saluran samping terhadap enkripsi TLS koneksi, serangan seperti CRIME dan BREACH. Jenis serangan ini mengharuskan penyerang cyber:
- Memaksa browser mengirimkan permintaan dengan payload yang dikendalikan oleh pelaku siber ke situs yang rentan melalui pengiriman formulir lintas situs atau dengan menyematkan situs di dalam iframe situs lain.
- Amati panjang respons terkompresi dan terenkripsi melalui jaringan.
Agar aplikasi rentan, ia harus memantulkan payload penyerang siber dalam respons, misalnya, dengan menyertakan jalur atau string kueri ke dalam respons. Dengan menggunakan panjang respons, cyberattacker dapat "menebak" informasi apa pun tentang respons, melewati enkripsi koneksi.
Secara umum, Blazor aplikasi dapat mengaktifkan kompresi melalui koneksi WebSocket dengan langkah-langkah keamanan yang sesuai:
Aplikasi ini dapat rentan ketika mengambil konten dari permintaan (misalnya, jalur atau string kueri) yang dapat dipengaruhi oleh penyerang siber dan mereproduksinya ke HTML halaman atau menjadikannya bagian dari respons.
Blazor menerapkan langkah-langkah keamanan berikut secara otomatis:
Ketika kompresi dikonfigurasi, Blazor secara otomatis memblokir penyematan aplikasi ke dalam iframe, yang memblokir respons awal (tidak terkompresi) dari server agar tidak merender dan menghalangi koneksi WebSocket dari awal.
Pembatasan penyematan aplikasi ke dalam iframe dapat dilonggarkan. Namun, melonggarkan pembatasan dapat mengekspos aplikasi terhadap penyerangan jika dokumen yang di-embed disusupi melalui kerentanan cross-site scripting, karena hal itu memberi peretas cara untuk mengeksekusi serangan.
Biasanya untuk jenis serangan ini terjadi, aplikasi harus berulang kali mereproduksi konten dalam respons sehingga cyberattacker dapat menebak respons. Mengingat bagaimana Blazor merender (hanya sekali, kemudian menghasilkan perbedaan konten hanya untuk elemen yang berubah), hal ini sulit dicapai oleh penyerang siber. Namun, bukan tidak mungkin bagi penyerang siber, jadi kehati-hatian harus dilakukan untuk menghindari penyajian informasi sensitif bersama informasi eksternal yang dapat dimanipulasi oleh penyerang siber. Beberapa contohnya adalah:
Render Informasi Pengidentifikasi Pribadi (PII) pada halaman secara bersamaan dengan merender data database yang ditambahkan oleh pengguna lain.
Merender informasi PII ke halaman secara bersamaan dengan data yang berasal dari pengguna lain melalui JS interop atau layanan singleton lokal di server.
Secara umum, kami sarankan Anda menghindari komponen penyajian yang berisi informasi sensitif bersama komponen yang dapat merender data dari sumber yang tidak tepercaya sebagai bagian dari batch render yang sama. Sumber yang tidak tepercaya termasuk parameter rute, string kueri, data dari JS interop, dan sumber data lain yang dapat dikontrol pengguna pihak ketiga (database, layanan eksternal).
Kondisi bersama
Aplikasi sisi Blazor server berada di memori server, dan beberapa sesi aplikasi dihosting dalam proses yang sama. Untuk setiap sesi aplikasi, Blazor memulai sirkuit dengan cakupan kontainer injeksi dependensi-nya sendiri, sehingga layanan yang terlingkup bersifat unik untuk setiap sesi Blazor.
Peringatan
Kami tidak merekomendasikan aplikasi pada server yang sama berbagi status menggunakan layanan singleton kecuali kehati-hatian ekstrem dilakukan, karena hal ini dapat memperkenalkan kerentanan keamanan, seperti membocorkan status pengguna di berbagai sirkuit.
Anda dapat menggunakan layanan singleton stateful pada aplikasi Blazor jika dirancang khusus untuk itu. Misalnya, penggunaan cache memori singleton dapat diterima karena cache memori memerlukan kunci untuk mengakses entri tertentu. Mengasumsikan pengguna tidak memiliki kontrol atas kunci cache yang digunakan dengan cache, status yang disimpan di cache tidak menyebar di seluruh sirkuit.
Untuk panduan umum tentang manajemen status, lihat Blazor.
IHttpContextAccessor
/HttpContext
Untuk informasi selengkapnya, lihat IHttpContextAccessor/HttpContext di aplikasi ASP.NET Core Blazor.
Kelelahan sumber daya
Kelelahan sumber daya dapat terjadi ketika klien berinteraksi dengan server dan menyebabkan server mengonsumsi sumber daya yang berlebihan. Konsumsi sumber daya yang berlebihan terutama memengaruhi:
Serangan Denial of Service (DoS) biasanya berusaha menghabiskan sumber daya aplikasi atau server. Namun, kelelahan sumber daya belum tentu merupakan hasil dari serangan pada sistem. Misalnya, sumber daya terbatas dapat habis karena permintaan pengguna yang tinggi. DoS tercakup lebih lanjut di bagian DoS.
Sumber daya di luar kerangka kerja Blazor, seperti database dan handle berkas (digunakan untuk membaca dan menulis berkas), mungkin juga mengalami kehabisan sumber daya. Untuk informasi selengkapnya, lihat praktik terbaik inti ASP.NET.
Unit Pemrosesan Pusat (CPU)
Kelelahan CPU dapat terjadi ketika satu atau beberapa klien memaksa server untuk melakukan pekerjaan CPU intensif.
Misalnya, pertimbangkan aplikasi yang menghitung angka Fibonnacci. Angka Fibonnacci diproduksi dari urutan Fibonnacci, di mana setiap angka dalam urutan adalah jumlah dari dua angka sebelumnya. Jumlah pekerjaan yang diperlukan untuk mencapai jawaban tergantung pada panjang urutan dan ukuran nilai awal. Jika aplikasi tidak menempatkan batas pada permintaan klien, perhitungan intensif CPU dapat mendominasi waktu CPU dan mengurangi performa tugas lain. Konsumsi sumber daya yang berlebihan adalah masalah keamanan yang memengaruhi ketersediaan.
Kelelahan CPU menjadi perhatian semua aplikasi yang menghadap publik. Di aplikasi web reguler, permintaan dan koneksi kehabisan waktu sebagai perlindungan, tetapi Blazor aplikasi tidak memberikan perlindungan yang sama. Blazor aplikasi harus menyertakan pemeriksaan dan batas yang sesuai sebelum melakukan pekerjaan yang berpotensi intensif CPU.
Memori
Kelelahan memori dapat terjadi ketika satu atau beberapa klien memaksa server untuk mengonsumsi sejumlah besar memori.
Misalnya, pertimbangkan aplikasi dengan komponen yang menerima dan menampilkan daftar item. Blazor Jika aplikasi tidak menempatkan batasan jumlah item yang diizinkan atau jumlah item yang dirender kembali ke klien, pemrosesan dan penyajian intensif memori dapat mendominasi memori server ke titik di mana performa server menderita. Server dapat mengalami kerusakan atau melambat sedemikian rupa sehingga tampak bermasalah.
Pertimbangkan skenario berikut untuk mempertahankan dan menampilkan daftar item yang berkaitan dengan skenario potensi kelelahan memori di server:
- Elemen dalam
List<T>
properti atau bidang menggunakan memori dari server. Jika aplikasi memungkinkan daftar item tumbuh tidak terbatas, ada risiko server kehabisan memori. Kehabisan memori menyebabkan sesi saat ini mengalami crash dan semua sesi bersamaan dalam instans server tersebut menerima pengecualian kehabisan memori. Untuk mencegah skenario ini terjadi, aplikasi harus menggunakan struktur data yang memberlakukan batas item pada pengguna bersamaan. - Jika skema halaman tidak digunakan untuk penyajian, server menggunakan memori tambahan untuk objek yang tidak terlihat di UI. Tanpa batas jumlah item, tuntutan memori dapat menghabiskan memori server yang tersedia. Untuk mencegah skenario ini, gunakan salah satu pendekatan berikut:
- Gunakan daftar paginasi saat penyajian.
- Hanya tampilkan 100 hingga 1.000 item pertama dan mengharuskan pengguna memasukkan kriteria pencarian untuk menemukan item di luar item yang ditampilkan.
- Untuk skenario penyajian yang lebih canggih, terapkan daftar atau kisi yang mendukung virtualisasi. Dengan menggunakan virtualisasi, daftar hanya merender subset item yang saat ini terlihat oleh pengguna. Saat pengguna berinteraksi dengan bilah gulir di UI, komponen hanya merender item yang diperlukan untuk ditampilkan. Item yang saat ini tidak diperlukan untuk tampilan dapat ditahan di penyimpanan sekunder, yang merupakan pendekatan ideal. Item yang tidak ditampilkan juga dapat disimpan dalam memori, yang kurang ideal.
Catatan
Blazor memiliki dukungan bawaan untuk virtualisasi. Untuk informasi selengkapnya, lihat
Blazoraplikasi menawarkan model pemrograman yang serupa dengan kerangka kerja UI lain untuk aplikasi yang memiliki status, seperti WPF, Windows Forms, atau Blazor WebAssembly. Perbedaan utamanya adalah bahwa dalam beberapa kerangka kerja UI memori yang digunakan oleh aplikasi milik klien dan hanya memengaruhi klien individual tersebut. Misalnya, aplikasi Blazor WebAssembly berjalan sepenuhnya pada klien dan hanya menggunakan sumber daya memori klien. Untuk aplikasi sisi Blazor server, memori yang digunakan oleh aplikasi milik server dan dibagikan di antara klien pada instans server.
Tuntutan memori sisi server adalah pertimbangan untuk semua aplikasi Blazor sisi server. Namun, sebagian besar aplikasi web bersifat tanpa status, dan memori yang digunakan saat memproses permintaan dilepaskan ketika respons diberikan kembali. Sebagai rekomendasi umum, jangan izinkan klien untuk mengalokasikan jumlah memori yang tidak terikat seperti di aplikasi sisi server lain yang mempertahankan koneksi klien. Memori yang digunakan oleh aplikasi sisi Blazor server bertahan untuk waktu yang lebih lama daripada satu permintaan.
Catatan
Selama pengembangan, profiler dapat digunakan atau menangkap jejak untuk menilai kebutuhan memori klien. Profiler atau jejak tidak akan menangkap memori yang dialokasikan untuk klien tertentu. Untuk menangkap penggunaan memori klien tertentu selama pengembangan, ambil cadangan dan periksa permintaan memori semua objek yang berakar di sirkuit pengguna.
Sambungan klien
Kelelahan koneksi dapat terjadi ketika satu atau beberapa klien membuka terlalu banyak koneksi bersamaan ke server, mencegah klien lain membuat koneksi baru.
Blazor klien membuat satu koneksi per sesi dan menjaga koneksi tetap terbuka selama jendela browser terbuka. Mengingat sifat koneksi yang persisten dan sifat stateful dari aplikasi sisi Blazor server, penipisan koneksi merupakan risiko lebih besar terhadap ketersediaan aplikasi.
Tidak ada batasan jumlah koneksi per pengguna untuk aplikasi. Jika aplikasi memerlukan batas koneksi, lakukan satu atau beberapa pendekatan berikut:
- Memerlukan autentikasi, yang secara alami membatasi kemampuan pengguna yang tidak sah untuk terhubung ke aplikasi. Agar skenario ini efektif, pengguna harus dicegah untuk menyediakan pengguna baru sesuai permintaan.
- Batasi jumlah koneksi per pengguna. Membatasi koneksi dapat dicapai melalui pendekatan berikut. Berhati-hatilah untuk memungkinkan pengguna sah mengakses aplikasi (misalnya, saat batas koneksi ditetapkan berdasarkan alamat IP klien).
- Tingkat aplikasi
- Ekstensibilitas perutean titik akhir.
- Memerlukan autentikasi untuk terhubung ke aplikasi dan melacak sesi aktif per pengguna.
- Tolak sesi baru setelah mencapai batas.
- Memproksi koneksi WebSocket ke aplikasi dengan menggunakan proksi, seperti layanan SignalR yang melakukan multipleks koneksi dari klien ke aplikasi. Ini menyediakan aplikasi dengan kapasitas koneksi yang lebih besar daripada yang dapat dibuat oleh klien tunggal, mencegah klien dari menghabiskan koneksi ke server.
- Tingkat server: Gunakan proksi/gateway di depan aplikasi.
- Azure Application Gateway adalah load balancer lalu lintas web (OSI layer 7) yang memungkinkan Anda mengelola lalu lintas ke aplikasi web Anda. Untuk informasi selengkapnya, lihat Gambaran umum dukungan WebSocket di dalam Application Gateway.
- Azure Front Door adalah layanan penyeimbang beban untuk mendistribusikan beban kerja Anda di beberapa sumber daya komputasi.
- Tingkat aplikasi
- Memerlukan autentikasi, yang secara alami membatasi kemampuan pengguna yang tidak sah untuk terhubung ke aplikasi. Agar skenario ini efektif, pengguna harus dicegah untuk menyediakan pengguna baru sesuai permintaan.
- Batasi jumlah koneksi per pengguna. Membatasi koneksi dapat dicapai melalui pendekatan berikut. Berhati-hatilah untuk memungkinkan pengguna sah mengakses aplikasi (misalnya, saat batas koneksi ditetapkan berdasarkan alamat IP klien).
- Tingkat aplikasi
- Ekstensibilitas perutean titik akhir.
- Memerlukan autentikasi untuk terhubung ke aplikasi dan melacak sesi aktif per pengguna.
- Tolak sesi baru setelah mencapai batas.
- Memproksi koneksi WebSocket ke aplikasi dengan menggunakan proksi, seperti layanan SignalR yang melakukan multipleks koneksi dari klien ke aplikasi. Ini menyediakan aplikasi dengan kapasitas koneksi yang lebih besar daripada yang dapat dibuat oleh klien tunggal, mencegah klien dari menghabiskan koneksi ke server.
- Tingkat server
- Gunakan proksi/gateway di depan aplikasi.
- Meskipun Long Polling didukung untuk Blazor aplikasi, WebSockets adalah protokol transport yang direkomendasikan. Sebaiknya pilih proksi/gateway yang mendukung WebSocket.
- Tingkat aplikasi
Serangan Denial of Service (DoS), yaitu serangan yang bertujuan membuat layanan tidak tersedia.
Serangan Denial of Service (DoS) melibatkan klien yang menyebabkan server kehabisan satu atau beberapa sumber dayanya membuat aplikasi tidak tersedia. Blazor aplikasi mencakup batas default dan mengandalkan pada ASP.NET Core serta batasan lain yang diatur di SignalR untuk melindungi dari serangan DoS:
- CircuitOptions.DisconnectedCircuitMaxRetained
- CircuitOptions.DisconnectedCircuitRetentionPeriod
- CircuitOptions.JSInteropDefaultCallTimeout
- CircuitOptions.MaxBufferedUnacknowledgedRenderBatches
- HubConnectionContextOptions.MaximumReceiveMessageSize
Untuk informasi selengkapnya dan contoh pengodatan konfigurasi, lihat artikel berikut ini:
Interaksi dengan browser (klien)
Klien berinteraksi dengan server melalui JS pengiriman peristiwa interop dan penyelesaian render. JS komunikasi interop berjalan dua arah antara JavaScript dan .NET:
- Peristiwa browser dikirim dari klien ke server dengan cara asinkron.
- Server menanggapi dengan menggambarkan ulang UI secara asinkron jika diperlukan.
Fungsi JavaScript yang dipanggil dari .NET
Untuk panggilan dari metode .NET ke JavaScript:
- Semua pemanggilan memiliki batas waktu yang dapat dikonfigurasi, setelah itu mereka gagal dan mengembalikan OperationCanceledException ke pemanggil.
- Ada batas waktu default untuk panggilan (CircuitOptions.JSInteropDefaultCallTimeout) satu menit. Untuk mengonfigurasi batas ini, lihat Memanggil fungsi JavaScript dari metode .NET di ASP.NET Core Blazor.
- Token pembatalan dapat disediakan untuk mengontrol pembatalan berdasarkan per panggilan. Andalkan batas waktu panggilan default jika memungkinkan dan atur batas waktu pada panggilan ke klien jika token pembatalan disediakan.
- Hasil panggilan JavaScript tidak dapat dipercaya. Klien Blazor aplikasi yang berjalan di browser mencari fungsi JavaScript untuk dipanggil. Fungsi ini dipanggil, dan kemudian dapat menghasilkan hasil atau kesalahan. Klien berbahaya dapat mencoba:
- Menyebabkan masalah pada aplikasi dengan mengembalikan pesan kesalahan dari fungsi JavaScript.
- Menginduksi perilaku yang tidak diinginkan di server dengan mengembalikan hasil yang tidak terduga dari fungsi JavaScript.
Lakukan tindakan pencegahan berikut untuk melindungi dari skenario sebelumnya:
- Gunakan JS panggilan interop dalam pernyataan
try-catch
untuk mengatasi kesalahan yang mungkin terjadi selama pemanggilan. Untuk informasi selengkapnya, lihat Menangani kesalahan di aplikasi ASP.NET CoreBlazor. - Validasi data yang dikembalikan dari JS pemanggilan interop, termasuk pesan kesalahan, sebelum melakukan tindakan apa pun.
Metode .NET yang dipanggil dari browser
Jangan percayai panggilan dari JavaScript ke metode .NET. Ketika metode .NET diekspos ke JavaScript, pertimbangkan bagaimana metode .NET dipanggil:
- Perlakukan metode .NET mana pun yang diekspos ke JavaScript seperti Anda memperlakukan titik akhir publik dari aplikasi.
- Validasi masukan.
- Pastikan bahwa nilai berada dalam rentang yang diharapkan.
- Pastikan bahwa pengguna memiliki izin untuk melakukan tindakan yang diminta.
- Jangan mengalokasikan jumlah sumber daya yang berlebihan sebagai bagian dari pemanggilan metode .NET. Misalnya, lakukan pemeriksaan dan tetapkan batas pada penggunaan CPU dan memori.
- Mempertimbangkan bahwa metode statis dan instans dapat diekspos ke klien JavaScript. Hindari berbagi status di seluruh sesi kecuali jika desain menuntut berbagi status dengan batasan yang tepat.
- Untuk metode instance yang disediakan melalui objek DotNetObjectReference yang awalnya dibuat melalui injeksi dependensi (DI), objek harus didaftarkan sebagai objek berlingkup. Ini berlaku untuk layanan DI apa pun yang digunakan aplikasi.
- Untuk metode statis, hindari menetapkan keadaan yang tidak dapat dibatasi pada klien kecuali aplikasi dengan sengaja berbagi keadaan secara desain di antara semua pengguna pada instans server.
- Hindari meneruskan data yang disediakan pengguna dalam parameter ke panggilan JavaScript. Jika meneruskan data dalam parameter benar-benar diperlukan, pastikan kode JavaScript menangani meneruskan data tanpa memperkenalkan kerawanan scripting lintas situs (XSS). Misalnya, jangan menulis data yang disediakan pengguna ke DOM dengan mengatur
innerHTML
properti elemen. Pertimbangkan untuk menggunakan Kebijakan Keamanan Konten (CSP) untuk menonaktifkaneval
dan primitif JavaScript tidak aman lainnya. Untuk informasi selengkapnya, lihat Menerapkan Kebijakan Keamanan Konten untuk panduan CSP ASP.NET Core Blazor dan MDN.
- Validasi masukan.
- Hindari menerapkan penanganan kustom untuk pemanggilan .NET di atas implementasi penanganan kerangka kerja. Mengekspos metode .NET ke browser adalah skenario lanjutan, tidak direkomendasikan untuk pengembangan umum Blazor .
Acara
Peristiwa menyediakan titik masuk ke aplikasi. Aturan yang sama untuk melindungi titik akhir di aplikasi web berlaku untuk penanganan peristiwa di Blazor aplikasi. Klien berbahaya dapat mengirim data apa pun yang ingin dikirim sebagai payload untuk suatu peristiwa.
Contohnya:
- Peristiwa perubahan untuk
<select>
dapat mengirim nilai yang tidak berada dalam opsi yang disajikan aplikasi kepada klien. -
<input>
dapat mengirimkan data teks apa pun ke server dengan memintas validasi di sisi klien.
Aplikasi harus memvalidasi data untuk setiap peristiwa yang ditangani aplikasi. Komponen kerangka kerja Blazormelakukan validasi dasar. Jika aplikasi menggunakan komponen formulir kustom, kode kustom harus ditulis untuk memvalidasi data peristiwa yang sesuai.
Peristiwa tidak sinkron, sehingga beberapa peristiwa dapat dikirim ke server sebelum aplikasi memiliki waktu untuk bereaksi dengan menghasilkan render baru. Ini memiliki beberapa implikasi keamanan untuk dipertimbangkan. Membatasi tindakan klien di aplikasi harus dilakukan di dalam penanganan aktivitas dan tidak bergantung pada status tampilan yang dirender saat ini.
Pertimbangkan komponen penghitung yang seharusnya memungkinkan pengguna untuk menaikkan penghitung maksimal tiga kali. Tombol untuk meningkatkan penghitung secara kondisional didasarkan pada nilai count
:
<p>Count: @count</p>
@if (count < 3)
{
<button @onclick="IncrementCount" value="Increment count" />
}
@code
{
private int count = 0;
private void IncrementCount()
{
count++;
}
}
Klien dapat mengirimkan satu atau beberapa peristiwa kenaikan sebelum kerangka kerja menghasilkan render baru komponen ini. Hasilnya adalah bahwa pengguna dapat meningkatkan count
lebih dari tiga kali karena UI tidak menghapus tombol cukup cepat. Cara yang benar untuk mencapai tiga batas kenaikan count
ditunjukkan dalam contoh berikut:
<p>Count: @count</p>
@if (count < 3)
{
<button @onclick="IncrementCount" value="Increment count" />
}
@code
{
private int count = 0;
private void IncrementCount()
{
if (count < 3)
{
count++;
}
}
}
Dengan menambahkan pemeriksaan if (count < 3) { ... }
di dalam handler, keputusan untuk meningkatkan count
didasarkan pada status aplikasi saat ini. Keputusan tidak didasarkan pada status UI seperti pada contoh sebelumnya, yang mungkin kedaluarsa sementara.
Melindungi dari pengiriman ganda
Jika panggilan balik peristiwa memanggil operasi jangka panjang secara asinkron, seperti mengambil data dari layanan atau database eksternal, pertimbangkan untuk menggunakan perlindungan. Perlindungan dapat mencegah pengguna mengantre beberapa operasi saat operasi sedang berlangsung dengan umpan balik visual. Kode dari komponen berikut mengatur isLoading
untuk true
saat DataService.GetDataAsync
mendapatkan data dari server. Sementara isLoading
adalah true
, tombol dinonaktifkan di UI:
<button disabled="@isLoading" @onclick="UpdateData">Update</button>
@code {
private bool isLoading;
private Data[] data = Array.Empty<Data>();
private async Task UpdateData()
{
if (!isLoading)
{
isLoading = true;
data = await DataService.GetDataAsync(DateTime.Now);
isLoading = false;
}
}
}
Pola perlindungan yang ditunjukkan dalam contoh sebelumnya berfungsi jika operasi latar belakang dijalankan secara asinkron dengan async
-await
pola.
Batalkan lebih awal dan hindari penggunaan setelah dibuang
Selain menggunakan perlindungan seperti yang dijelaskan di bagian Lindungi dari beberapa pengiriman, pertimbangkan untuk menggunakan CancellationToken untuk membatalkan operasi jangka panjang ketika komponen dibuang. Pendekatan ini memiliki manfaat tambahan untuk menghindari penggunaan setelah dibuang dalam komponen:
@implements IDisposable
...
@code {
private readonly CancellationTokenSource TokenSource =
new CancellationTokenSource();
private async Task UpdateData()
{
...
data = await DataService.GetDataAsync(DateTime.Now, TokenSource.Token);
if (TokenSource.Token.IsCancellationRequested)
{
return;
}
...
}
public void Dispose()
{
TokenSource.Cancel();
}
}
Hindari peristiwa yang menghasilkan data dalam jumlah besar
Beberapa peristiwa DOM, seperti oninput
atau onscroll
, dapat menghasilkan sejumlah besar data. Hindari menggunakan event ini di server sisi Blazor.
Panduan keamanan tambahan
Panduan untuk mengamankan aplikasi ASP.NET Core berlaku untuk aplikasi sisi Blazor server dan dibahas di bagian berikut dari artikel ini:
- Pencatatan dan data sensitif
- Melindungi informasi saat transit dengan HTTPS
- Pembuatan skrip lintas situs (XSS)
- Perlindungan lintas domain
- Pembajakan klik
- Buka pengalihan
Pengelogan dan data sensitif
JS interaksi interop antara klien dan server dicatat dalam log server dengan kejadian ILogger. Blazor menghindari pencatatan informasi sensitif, seperti peristiwa aktual atau JS input dan output interop.
Ketika kesalahan terjadi di server, sistem memberi tahu klien dan mengakhiri sesi. Klien menerima pesan kesalahan umum yang dapat dilihat di alat pengembang browser.
Kesalahan sisi klien tidak menyertakan tumpukan panggilan dan tidak memberikan detail tentang penyebab kesalahan, tetapi log server berisi informasi tersebut. Untuk tujuan pengembangan, informasi kesalahan sensitif dapat disediakan untuk klien dengan mengaktifkan kesalahan terperinci.
Peringatan
Mengekspos informasi kesalahan kepada klien di Internet adalah risiko keamanan yang harus selalu dihindari.
Melindungi informasi saat transit dengan HTTPS
Blazor menggunakan SignalR untuk komunikasi antara klien dan server. Blazor biasanya menggunakan transport yang SignalR dinegosiasikan, yang biasanya WebSockets.
Blazor tidak memastikan integritas dan kerahasiaan data yang dikirim antara server dan klien. Selalu gunakan HTTPS.
Pembuatan skrip lintas situs (XSS)
Pembuatan skrip lintas situs (XSS) memungkinkan pihak yang tidak berwenang untuk menjalankan logika sewenang-wenang dalam konteks browser. Aplikasi yang disusupi berpotensi menjalankan kode arbitrer pada klien. Kerentanan dapat digunakan untuk berpotensi melakukan sejumlah tindakan berbahaya terhadap server:
- Kirim peristiwa palsu/tidak valid ke server.
- Pengiriman gagal/penyelesaian render tidak valid.
- Hindari mengirimkan penyelesaian render.
- Kirim panggilan interop dari JavaScript ke .NET.
- Ubah respons panggilan interop dari .NET ke JavaScript.
- Hindari mengirimkan .NET ke JS hasil interop.
Blazor Kerangka kerja mengambil langkah-langkah untuk melindungi dari beberapa ancaman sebelumnya:
- Berhenti menghasilkan pembaruan UI baru jika klien tidak mengakui batch render. Dikonfigurasi dengan CircuitOptions.MaxBufferedUnacknowledgedRenderBatches.
- Pemanggilan .NET ke JavaScript akan diakhiri setelah satu menit jika tidak menerima respons dari klien. Dikonfigurasi dengan CircuitOptions.JSInteropDefaultCallTimeout.
- Melakukan validasi dasar pada semua input yang berasal dari browser selama JS interop:
- Referensi .NET valid dan dari jenis yang diharapkan oleh metode .NET.
- Data tidak rusak.
- Jumlah argumen yang benar untuk metode ada dalam payload.
- Argumen atau hasil dapat dideserialisasi dengan benar sebelum menjalankan metode.
- Melakukan validasi dasar pada semua input yang berasal dari browser melalui peristiwa yang dikirimkan.
- Kejadian ini memiliki jenis yang valid.
- Data untuk acara dapat dideserialisasi.
- Ada pengendali acara yang terkait dengan acara tersebut.
Selain perlindungan yang diterapkan kerangka kerja, aplikasi harus dikodekan oleh pengembang untuk melindungi dari ancaman dan mengambil tindakan yang sesuai:
- Selalu validasi data saat menangani peristiwa.
- Ambil tindakan yang tepat saat menerima data yang tidak valid:
- Abaikan data dan kembali. Ini memungkinkan aplikasi untuk terus memproses permintaan.
- Jika aplikasi menentukan bahwa input tidak sah dan tidak dapat diproduksi oleh klien yang sah, berikan pengecualian. Melempar pengecualian memutuskan sirkuit dan mengakhiri sesi.
- Jangan percayai pesan kesalahan yang diberikan oleh penyelesaian batch render yang disertakan dalam log. Kesalahan disediakan oleh klien dan umumnya tidak bisa diandalkan, karena klien mungkin terkompromi.
- Jangan mempercayai input pada panggilan JS interop dalam kedua arah antara metode .NET dan JavaScript.
- Aplikasi ini bertanggung jawab untuk memvalidasi bahwa konten argumen dan hasil adalah valid, walaupun argumen atau hasil telah dideserialisasi dengan benar.
Agar kerentanan XSS ada, aplikasi harus menggabungkan input pengguna di halaman yang dirender.
Blazor menjalankan langkah waktu kompilasi di mana markup dalam .razor
file diubah menjadi logika C# prosedural. Pada waktu berjalan, logika C# membangun pohon render yang menggambarkan elemen, teks, dan komponen anak. Ini diterapkan ke DOM browser melalui urutan instruksi JavaScript (atau diserialisasikan ke HTML dalam kasus pra-penyajian):
- Input pengguna yang dirender melalui sintaks normal Razor (misalnya,
@someStringValue
) tidak mengekspos kerentanan XSS karena Razor sintaks ditambahkan ke DOM melalui perintah yang hanya dapat menulis teks. Bahkan jika nilai menyertakan markup HTML, nilai ditampilkan sebagai teks statis. Saat melakukan pra-penyajian, output dikodekan HTML, yang juga menampilkan konten sebagai teks statis. - Penulis komponen dapat menulis komponen di C# tanpa menggunakan Razor. Pembuat komponen bertanggung jawab untuk menggunakan API yang benar saat memancarkan output. Misalnya, gunakan
builder.AddContent(0, someUserSuppliedString)
dan bukanbuilder.AddMarkupContent(0, someUserSuppliedString)
, karena yang terakhir dapat membuat kerentanan XSS.
- Input pengguna yang dirender melalui sintaks normal Razor (misalnya,
@someStringValue
) tidak mengekspos kerentanan XSS karena Razor sintaks ditambahkan ke DOM melalui perintah yang hanya dapat menulis teks. Bahkan jika nilai menyertakan markup HTML, nilai ditampilkan sebagai teks statis. Saat melakukan pra-penyajian, output dikodekan HTML, yang juga menampilkan konten sebagai teks statis. - Tag skrip tidak diizinkan dan tidak boleh disertakan dalam pohon render komponen aplikasi. Jika tag skrip disertakan dalam markup komponen, kesalahan waktu kompilasi dihasilkan.
- Penulis komponen dapat menulis komponen di C# tanpa menggunakan Razor. Pembuat komponen bertanggung jawab untuk menggunakan API yang benar saat memancarkan output. Misalnya, gunakan
builder.AddContent(0, someUserSuppliedString)
dan bukanbuilder.AddMarkupContent(0, someUserSuppliedString)
, karena yang terakhir dapat membuat kerentanan XSS.
Pertimbangkan untuk mengurangi kerentanan XSS lebih lanjut. Misalnya, terapkan Kebijakan Keamanan Konten (CSP) yang ketat. Untuk informasi selengkapnya, lihat Menerapkan Kebijakan Keamanan Konten untuk panduan CSP ASP.NET Core Blazor dan MDN.
Untuk informasi selengkapnya, lihat Mencegah Scripting Lintas Situs (XSS) di ASP.NET Core.
Perlindungan lintas sumber
Serangan lintas asal melibatkan klien dari asal yang berbeda yang melakukan tindakan terhadap server. Tindakan berbahaya biasanya adalah permintaan GET atau formulir POST (Pemalsuan Permintaan Lintas Situs, CSRF), tetapi membuka WebSocket berbahaya juga dimungkinkan.
- Aplikasi dapat diakses lintas domain kecuali jika langkah-langkah tambahan diambil untuk mencegahnya. Untuk menonaktifkan akses lintas asal, Anda dapat menonaktifkan CORS di titik akhir dengan menambahkan Middleware CORS ke dalam alur dan menambahkan DisableCorsAttribute ke metadata titik akhir Blazor atau membatasi kumpulan asal yang diperbolehkan dengan mengonfigurasi SignalR untuk Berbagi Sumber Daya Lintas Asal. Untuk panduan tentang pembatasan asal WebSocket, lihat Dukungan WebSocket di ASP.NET Core.
- Jika CORS diaktifkan, langkah tambahan mungkin diperlukan untuk melindungi aplikasi tergantung pada konfigurasi CORS. Jika CORS diaktifkan secara global, CORS dapat dinonaktifkan untuk BlazorSignalR hub dengan menambahkan DisableCorsAttribute metadata ke metadata titik akhir setelah memanggil MapBlazorHub pembangun rute titik akhir.
Untuk informasi selengkapnya, lihat Mencegah serangan Pemalsuan Permintaan Antar Situs (XSRF/CSRF) di ASP.NET Core.
Pembajakan klik
Pembajakan klik melibatkan menampilkan sebuah situs sebagai <iframe>
dalam situs lain dari asal yang berbeda untuk mengelabui pengguna melakukan tindakan di situs yang diserang.
Untuk melindungi aplikasi agar tidak ditampilkan dalam <iframe>
, gunakan Kebijakan Keamanan Konten (CSP) dan tajuk X-Frame-Options
. Untuk sintaks CSP, lihat Panduan CSP MDN.
Untuk informasi selengkapnya, lihat sumber daya berikut:
Buka pengalihan
Saat sesi aplikasi dimulai, server melakukan validasi dasar URL yang dikirim sebagai bagian dari memulai sesi. Kerangka kerja memeriksa bahwa URL dasar adalah induk URL saat ini sebelum membuat sirkuit. Tidak ada pemeriksaan tambahan yang dilakukan oleh kerangka kerja.
Saat pengguna memilih tautan pada klien, URL untuk tautan dikirim ke server, yang menentukan tindakan apa yang harus diambil. Misalnya, aplikasi dapat melakukan navigasi sisi klien atau menunjukkan ke browser untuk masuk ke lokasi baru.
Komponen juga dapat memicu permintaan navigasi secara terprogram melalui penggunaan NavigationManager. Dalam skenario seperti itu, aplikasi mungkin melakukan navigasi sisi klien atau menunjukkan ke browser untuk masuk ke lokasi baru.
Komponen harus:
- Hindari menggunakan input pengguna sebagai bagian dari argumen panggilan navigasi.
- Validasi argumen untuk memastikan bahwa target diizinkan oleh aplikasi.
Jika tidak, pengguna berbahaya dapat memaksa browser untuk membuka situs yang dikendalikan cyberattacker. Dalam skenario ini, cyberattacker mengelabui aplikasi agar menggunakan beberapa masukan pengguna sebagai bagian dari pemanggilan metode NavigationManager.NavigateTo.
Saran ini juga berlaku saat merender tautan sebagai bagian dari aplikasi:
- Jika memungkinkan, gunakan tautan relatif.
- Validasi bahwa tujuan tautan absolut valid sebelum menyertakannya di halaman.
Untuk informasi selengkapnya, lihat Mencegah serangan pengalihan terbuka di ASP.NET Core.
Daftar periksa keamanan
Daftar pertimbangan keamanan berikut ini tidak komprehensif:
- Memvalidasi argumen dari peristiwa.
- Validasi input dan hasil dari panggilan interop JS.
- Hindari menggunakan input pengguna (atau memvalidasi terlebih dahulu) untuk panggilan interop .NET ke JS.
- Mencegah klien mengalokasikan jumlah memori yang tidak terbatas.
- Data dalam komponen.
- DotNetObjectReference pengembalian objek ke klien.
- Lindungi dari pengiriman berganda.
- Batalkan proses yang berjalan lama ketika komponen dibuang.
- Hindari peristiwa yang menghasilkan data dalam jumlah besar.
- Hindari menggunakan input pengguna sebagai bagian dari panggilan ke NavigationManager.NavigateTo dan, jika tidak dapat dihindari, validasi input pengguna untuk URL terhadap daftar asal-usul yang diizinkan terlebih dahulu.
- Jangan membuat keputusan otorisasi berdasarkan status UI tetapi hanya dari status komponen.
- Pertimbangkan untuk menggunakan Kebijakan Keamanan Konten (CSP) untuk melindungi dari serangan XSS. Untuk informasi selengkapnya, lihat Menerapkan Kebijakan Keamanan Konten untuk panduan CSP ASP.NET Core Blazor dan MDN.
- Pertimbangkan untuk menggunakan CSP dan X-Frame-Options untuk melindungi dari click-jacking.
- Pastikan pengaturan CORS sesuai saat mengaktifkan CORS atau secara eksplisit menonaktifkan CORS untuk Blazor aplikasi.
- Uji untuk memastikan bahwa batas sisi server untuk Blazor aplikasi memberikan pengalaman pengguna yang dapat diterima tanpa tingkat risiko yang tidak dapat diterima.
ASP.NET Core