Bagikan melalui


Panduan mitigasi ancaman untuk penyajian sisi server interaktif ASP.NET Core Blazor

Catatan

Ini bukan versi terbaru dari artikel ini. Untuk rilis saat ini, lihat versi .NET 8 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 8 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 berumur panjang. 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 baik:

  • 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, seperti CRIME dan BREACH serangan. Jenis serangan ini mengharuskan penyerang:

  • Paksa browser untuk mengeluarkan permintaan dengan payload yang dikontrol penyerang ke situs yang rentan melalui posting formulir lintas situs atau dengan menyematkan situs di dalam iframe situs lain.
  • Amati panjang respons terkompresi dan terenkripsi melalui jaringan.

Agar aplikasi rentan, aplikasi harus mencerminkan payload dari penyerang dalam respons, misalnya, dengan menulis jalur atau string kueri ke dalam respons. Dengan menggunakan panjang respons, penyerang 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 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 mengekspos aplikasi untuk menyerang jika dokumen penyematan disusupi melalui kerentanan pembuatan skrip lintas situs, karena itu memberi penyerang cara untuk mengeksekusi serangan.

  • Biasanya jenis serangan ini terjadi, aplikasi harus berulang kali mereproduksi konten dalam respons sehingga penyerang dapat menebak respons. Mengingat bagaimana Blazor render (dirender sekali dan kemudian menghasilkan perbedaan konten hanya untuk elemen yang berubah) ini sulit untuk dicapai penyerang. Namun, tidak mustahil bagi penyerang, jadi perawatan harus diambil untuk menghindari penyajian informasi sensitif bersama informasi eksternal yang dapat dimanipulasi oleh penyerang. 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).

Status 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 dependensinya sendiri, sehingga layanan terlingkup unik per Blazor sesi.

Peringatan

Kami tidak merekomendasikan aplikasi pada status berbagi server yang sama menggunakan layanan singleton kecuali perawatan ekstrem diambil, karena ini dapat memperkenalkan kerentanan keamanan, seperti membocorkan status pengguna di seluruh sirkuit.

Anda dapat menggunakan layanan singleton stateful di Blazor aplikasi jika dirancang khusus untuk itu. Misalnya, penggunaan cache memori singleton dapat diterima karena cache memori memerlukan kunci untuk mengakses entri tertentu. Dengan asumsi pengguna tidak memiliki kontrol atas kunci cache yang digunakan dengan cache, status yang disimpan di cache tidak bocor di seluruh sirkuit.

Untuk panduan umum tentang manajemen status, lihat manajemen status ASP.NET CoreBlazor.

IHttpContextAccessor/HttpContext dalam Razor komponen

IHttpContextAccessor harus dihindari dengan penyajian interaktif karena tidak tersedia yang valid HttpContext .

IHttpContextAccessor dapat digunakan untuk komponen yang dirender secara statis di server. Namun, sebaiknya hindari jika memungkinkan.

HttpContext dapat digunakan sebagai parameter kaskading hanya dalam komponen akar yang dirender secara statis untuk tugas umum, seperti memeriksa dan memodifikasi header atau properti lain dalam App komponen (Components/App.razor). Nilainya selalu null untuk penyajian interaktif.

[CascadingParameter]
public HttpContext? HttpContext { get; set; }

Untuk skenario di mana HttpContext diperlukan dalam komponen interaktif, sebaiknya mengalirkan data melalui status komponen persisten dari server. Untuk informasi selengkapnya, lihat Skenario keamanan tambahan ASP.NET Core Blazor sisi server.

Jangan gunakan IHttpContextAccessor/HttpContext secara langsung atau tidak langsung dalam Razor komponen aplikasi sisi Blazor server. Blazor aplikasi berjalan di luar konteks alur ASP.NET Core. HttpContext tidak dijamin tersedia dalam IHttpContextAccessor, dan HttpContext tidak dijamin untuk menyimpan konteks yang memulai Blazor aplikasi.

Pendekatan yang direkomendasikan untuk meneruskan status permintaan ke Blazor aplikasi adalah melalui parameter komponen akar selama penyajian awal aplikasi. Atau, aplikasi dapat menyalin data ke dalam layanan tercakup dalam peristiwa siklus hidup inisialisasi komponen akar untuk digunakan di seluruh aplikasi. Untuk informasi selengkapnya, lihat Skenario keamanan tambahan ASP.NET Core Blazor sisi server.

Aspek penting dari keamanan sisi Blazor server adalah bahwa pengguna yang melekat pada sirkuit tertentu mungkin diperbarui pada beberapa titik setelah Blazor sirkuit dibuat tetapi IHttpContextAccessortidak diperbarui. Untuk informasi selengkapnya tentang mengatasi situasi ini dengan layanan kustom, lihat Skenario keamanan tambahan ASP.NET Core Blazor sisi server.

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 Blazor kerangka kerja, seperti database dan handel file (digunakan untuk membaca dan menulis file), mungkin juga mengalami kelelahan sumber daya. Untuk informasi selengkapnya, lihat praktik terbaik inti ASP.NET.

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 mungkin crash atau lambat ke titik yang tampaknya mengalami crash.

Pertimbangkan skenario berikut untuk mempertahankan dan menampilkan daftar item yang berkaitan dengan skenario potensi kelelahan memori di server:

  • Item dalam List<T> properti atau bidang menggunakan memori server. Jika aplikasi memungkinkan daftar item tumbuh tidak terbatas, ada risiko server kehabisan memori. Kehabisan memori menyebabkan sesi saat ini berakhir (crash) dan semua sesi bersamaan dalam instans server tersebut menerima pengecualian di luar 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 diputar juga dapat disimpan dalam memori, yang kurang ideal.

Catatan

Blazor memiliki dukungan bawaan untuk virtualisasi. Untuk informasi selengkapnya, lihat virtualisasi komponen ASP.NET CoreRazor.

Blazoraplikasi menawarkan model pemrograman serupa ke kerangka kerja UI lain untuk aplikasi stateful, seperti WPF, Formulir Windows, 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 sisi Blazor server. Namun, sebagian besar aplikasi web tidak memiliki status, dan memori yang digunakan saat memproses permintaan dirilis saat respons dikembalikan. 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 jejak yang ditangkap untuk menilai tuntutan 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

Koneksi kelelahan 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, kelelahan koneksi adalah risiko yang lebih besar untuk ketersediaan aplikasi.

Secara default, 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. Latihan peduli untuk memungkinkan pengguna yang sah mengakses aplikasi (misalnya, ketika batas koneksi dibuat berdasarkan alamat IP klien).
    • Di tingkat aplikasi:

      • Ekstensibilitas perutean titik akhir.
      • Memerlukan autentikasi untuk terhubung ke aplikasi dan melacak sesi aktif per pengguna.
      • Tolak sesi baru setelah mencapai batas.
      • Proksi koneksi WebSocket ke aplikasi melalui penggunaan proksi, seperti Layanan Azure SignalR yang melakukan multipleks koneksi dari klien ke aplikasi. Ini menyediakan aplikasi dengan kapasitas koneksi yang lebih besar daripada yang dapat dibuat klien tunggal, mencegah klien menghabiskan koneksi ke server.
    • Di tingkat server: Gunakan proksi/gateway di depan aplikasi. Misalnya, Azure Front Door memungkinkan Anda menentukan, mengelola, dan memantau perutean global lalu lintas web ke aplikasi dan berfungsi saat aplikasi dikonfigurasi untuk menggunakan Long Polling.

      Catatan

      Meskipun Long Polling didukung, WebSockets adalah protokol transportasi yang direkomendasikan. Mulai Februari 2023, Azure Front Door tidak mendukung WebSocket, tetapi dukungan untuk WebSocket sedang dikembangkan untuk rilis layanan di masa mendatang. Untuk informasi selengkapnya, lihat Mendukung koneksi WebSocket di Azure Front Door.

  • 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. Latihan peduli untuk memungkinkan pengguna yang sah mengakses aplikasi (misalnya, ketika batas koneksi dibuat berdasarkan alamat IP klien).
    • Di tingkat aplikasi:

      • Ekstensibilitas perutean titik akhir.
      • Memerlukan autentikasi untuk terhubung ke aplikasi dan melacak sesi aktif per pengguna.
      • Tolak sesi baru setelah mencapai batas.
      • Proksi koneksi WebSocket ke aplikasi melalui penggunaan proksi, seperti Layanan Azure SignalR yang melakukan multipleks koneksi dari klien ke aplikasi. Ini menyediakan aplikasi dengan kapasitas koneksi yang lebih besar daripada yang dapat dibuat klien tunggal, mencegah klien menghabiskan koneksi ke server.
    • Di tingkat server: Gunakan proksi/gateway di depan aplikasi.

      Catatan

      Meskipun Long Polling didukung, WebSockets adalah protokol transportasi yang direkomendasikan.

Serangan Denial of Service (DoS)

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 ASP.NET Core dan SignalR batasan lain yang diatur CircuitOptions untuk melindungi dari serangan DoS:

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 merespons penyajian UI secara asinkron seperlunya.

Fungsi JavaScript yang dipanggil dari .NET

Untuk panggilan dari metode .NET ke JavaScript:

  • Semua pemanggilan memiliki batas waktu yang dapat dikonfigurasi setelah gagal, mengembalikan OperationCanceledException ke pemanggil.
  • Hasil panggilan JavaScript tidak dapat dipercaya. Klien Blazor aplikasi yang berjalan di browser mencari fungsi JavaScript untuk dipanggil. Fungsi ini dipanggil, dan hasilnya atau kesalahan dihasilkan. Klien berbahaya dapat mencoba:
    • Menyebabkan masalah di aplikasi dengan mengembalikan 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:

  • Membungkus JS panggilan interop dalam try-catch pernyataan untuk memperhitungkan 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 mengambil tindakan apa pun.

Metode .NET yang dipanggil dari browser

Jangan percayai panggilan dari metode JavaScript ke .NET. Ketika metode .NET diekspos ke JavaScript, pertimbangkan bagaimana metode .NET dipanggil:

  • Perlakukan metode .NET apa pun yang diekspos ke JavaScript seperti yang Anda lakukan pada titik akhir publik ke aplikasi.
    • Validasi input.
      • 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 batas tempat pada penggunaan CPU dan memori.
    • Mempertimbangkan bahwa metode statis dan instans dapat diekspos ke klien JavaScript. Hindari berbagi status di seluruh sesi kecuali panggilan desain untuk berbagi status dengan batasan yang sesuai.
      • Untuk metode instans yang diekspos melalui DotNetObjectReference objek yang awalnya dibuat melalui injeksi dependensi (DI), objek harus didaftarkan sebagai objek tercakup. Ini berlaku untuk layanan DI apa pun yang digunakan aplikasi.
      • Untuk metode statis, hindari menetapkan status yang tidak dapat dicakup ke klien kecuali aplikasi secara eksplisit berbagi status berdasarkan desain di 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 kerentanan 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 menonaktifkan eval dan primitif JavaScript tidak aman lainnya. Untuk informasi selengkapnya, lihat Menerapkan Kebijakan Keamanan Konten untuk ASP.NET Core Blazor.
  • Hindari menerapkan pengiriman kustom pemanggilan .NET di atas implementasi pengiriman kerangka kerja. Mengekspos metode .NET ke browser adalah skenario lanjutan, tidak direkomendasikan untuk pengembangan umum Blazor .

Peristiwa

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.
  • Dapat <input> mengirim data teks apa pun ke server, melewati validasi sisi klien.

Aplikasi harus memvalidasi data untuk setiap peristiwa yang ditangani aplikasi. Komponen Blazor formulir kerangka kerja melakukan 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 count dapat bertambah selama tiga kali oleh pengguna karena tombol tidak dihapus oleh UI dengan cukup cepat. Cara yang benar untuk mencapai batas tiga count kenaikan 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 di if (count < 3) { ... } dalam handler, keputusan untuk kenaikan count didasarkan pada status aplikasi saat ini. Keputusan tidak didasarkan pada status UI seperti pada contoh sebelumnya, yang mungkin kedaluarsa sementara.

Menjaga dari beberapa pengiriman

Jika panggilan balik peristiwa memanggil operasi jangka panjang secara asinkron, seperti mengambil data dari layanan atau database eksternal, pertimbangkan untuk menggunakan penjaga. Penjaga dapat mencegah pengguna mengantre beberapa operasi saat operasi sedang berlangsung dengan umpan balik visual. Kode komponen berikut diatur isLoading ke 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 penjaga 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 penjaga seperti yang dijelaskan di bagian Jaga terhadap beberapa pengiriman , pertimbangkan CancellationToken untuk membatalkan operasi yang berjalan lama saat 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 peristiwa ini di server sisi Blazor server.

Panduan keamanan tambahan

Panduan untuk mengamankan aplikasi ASP.NET Core berlaku untuk aplikasi sisi Blazor server dan dibahas di bagian berikut dari artikel ini:

Pengelogan dan data sensitif

JS interaksi interop antara klien dan server dicatat dalam log server dengan ILogger instans. Blazor menghindari pencatatan informasi sensitif, seperti peristiwa aktual atau JS input dan output interop.

Ketika kesalahan terjadi di server, kerangka kerja memberi tahu klien dan merobek sesi. Secara default, 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

BlazorSignalR menggunakan untuk komunikasi antara klien dan server. Blazor biasanya menggunakan transportasi yang SignalR bernegosiasi, yang biasanya WebSocket.

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 pengiriman 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.
  • Waktu habis setiap panggilan .NET ke JavaScript setelah satu menit tanpa 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 cacat.
    • Jumlah argumen yang benar untuk metode ada dalam payload.
    • Argumen atau hasil dapat dideserialisasi dengan benar sebelum memanggil metode .
  • Melakukan validasi dasar di semua input yang berasal dari browser dari peristiwa yang dikirim:
    • Kejadian ini memiliki jenis yang valid.
    • Data untuk peristiwa dapat dideserialisasi.
    • Ada penanganan aktivitas yang terkait dengan peristiwa 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 kembalikan. Ini memungkinkan aplikasi untuk terus memproses permintaan.
    • Jika aplikasi menentukan bahwa input tidak sah dan tidak dapat diproduksi oleh klien yang sah, berikan pengecualian. Melemparkan air mata pengecualian ke sirkuit dan mengakhiri sesi.
  • Jangan percayai pesan kesalahan yang disediakan oleh penyelesaian batch render yang disertakan dalam log. Kesalahan disediakan oleh klien dan umumnya tidak dapat dipercaya, karena klien mungkin disusupi.
  • Jangan percaya input pada JS panggilan interop ke kedua arah antara metode JavaScript dan .NET.
  • Aplikasi ini bertanggung jawab untuk memvalidasi bahwa konten argumen dan hasil valid, bahkan jika argumen atau hasil 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 runtime, logika C# membangun pohon render yang menjelaskan 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.
  • 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 tidakbuilder.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 ASP.NET Core Blazor.

Untuk informasi selengkapnya, lihat Mencegah Scripting Lintas Situs (XSS) di ASP.NET Core.

Perlindungan lintas asal

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. Blazor aplikasi menawarkan jaminan yang sama bahwa aplikasi lain SignalR menggunakan penawaran protokol hub:

  • Aplikasi dapat diakses lintas asal kecuali langkah-langkah tambahan diambil untuk mencegahnya. Untuk menonaktifkan akses lintas asal, nonaktifkan CORS di titik akhir dengan menambahkan CORS Middleware ke alur dan menambahkan DisableCorsAttribute ke Blazor metadata titik akhir atau membatasi kumpulan asal yang diizinkan 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 penyajian situs sebagai <iframe> situs di dalam situs dari asal yang berbeda untuk mengelabui pengguna untuk melakukan tindakan di situs yang diserang.

Untuk melindungi aplikasi dari penyajian <iframe>di dalam , gunakan Kebijakan Keamanan Konten (CSP) dan X-Frame-Options header.

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 dikontrol penyerang. Dalam skenario ini, penyerang mengelabui aplikasi untuk menggunakan beberapa input pengguna sebagai bagian dari pemanggilan NavigationManager.NavigateTo metode.

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.
  • Memvalidasi input dan hasil dari JS panggilan interop.
  • Hindari menggunakan input pengguna (atau validasi sebelumnya) untuk .NET untuk JS melakukan interop panggilan.
  • Mencegah klien mengalokasikan jumlah memori yang tidak terikat.
  • Jaga dari beberapa pengiriman.
  • Batalkan operasi jangka panjang saat komponen dibuang.
  • Hindari peristiwa yang menghasilkan data dalam jumlah besar.
  • Hindari menggunakan input pengguna sebagai bagian dari panggilan ke NavigationManager.NavigateTo dan memvalidasi input pengguna untuk URL terhadap sekumpulan asal yang diizinkan terlebih dahulu jika tidak dapat dihindari.
  • 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 ASP.NET Core Blazor.
  • 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.