Episode ini mengubah cara kalian menulis kode yang aman: input validation, output encoding, pencegahan SQL injection, XSS, dan CSRF, pengamanan data sensitif, serta best practices keamanan yang diterapkan sejak hari pertama pengembangan.

Episode 12 mengamankan transportasi dan identitas; episode 13 mengamankan kode itu sendiri. Secure coding adalah disiplin menulis kode yang kebal terhadap pola serangan umum — bukan fitur yang ditambahkan di akhir, melainkan kebiasaan yang melekat di setiap baris.
Kalian akan belajar validasi input, encoding output, pencegahan injection, XSS, dan CSRF, pengelolaan data sensitif, serta praktik produksi yang diterapkan tim keamanan profesional. Banyak dari praktik ini sudah disediakan framework — tugas kalian adalah tidak menonaktifkannya.
Aturan emas: jangan pernah percaya input. Validasi di setiap batas sistem — API, file impor, dan form. Gunakan DataAnnotations yang sudah terpasang:
public class RegisterRequest
{
[Required, EmailAddress]
public string Email { get; set; }
[Required, MinLength(8)]
public string Password { get; set; }
}[EmailAddress] dan [MinLength(8)] memvalidasi input saat model binding. Dengan [ApiController], model yang tidak valid otomatis menghasilkan respons 400 — kalian tidak perlu menulis pemeriksaan manual.
Output yang mengandung input pengguna harus di-encoding agar tidak menjadi markup. Di Razor (Blazor dan MVC), encoding dilakukan otomatis:
@{
var nama = HttpUtility.HtmlEncode(userInput);
}
<p>Halo, @nama</p>HttpUtility.HtmlEncode(userInput) mengubah karakter berbahaya menjadi entitas HTML yang aman. Aturan sederhana: context menentukan encoding — HTML di Razor, SQL di query, URL di header. Encode sesuai konteks tempat data dikeluarkan.
SQL injection terjadi saat input digabungkan langsung ke string SQL. Selalu parameterize:
var hasil = await _db.Produk
.FromSqlRaw("SELECT * FROM Produk WHERE Nama = {0}", nama)
.ToListAsync();Placeholder {0} mengirim nama sebagai parameter, bukan bagian dari query — database memperlakukannya sebagai data murni. Jangan pernah menggabungkan variabel langsung ke string SQL, misalnya seperti contoh berbahaya berikut:
var sql = $"SELECT * FROM Produk WHERE Nama = '{nama}'";Pola di atas rentan SQL injection karena nilai pengguna ditempel langsung ke query. Sebagai gantinya, selalu kirim nilai sebagai parameter, seperti yang dilakukan FromSqlRaw dengan placeholder. Prinsip yang sama berlaku untuk raw ADO.NET: gunakan SqlParameter.
XSS (Cross-Site Scripting) terjadi saat script disuntikkan ke halaman. Pencegahannya adalah output encoding, yang sudah otomatis di Razor. CSRF (Cross-Site Request Forgery) memaksa pengguna mengirim request tak dikehendaki. Framework menyediakan anti-forgery token:
builder.Services.AddAntiforgery(options =>
{
options.HeaderName = "X-CSRF-TOKEN";
});AddAntiforgery menyediakan token yang diverifikasi untuk permintaan yang mengubah state. Token dikirim lewat header X-CSRF-TOKEN dan divalidasi middleware — memastikan request benar-benar berasal dari pengguna yang disetujui.
Kebocoran paling umum bukan karena peretasan, tetapi karena log dan response menampilkan data sensitif. Perhatikan titik-titik berikut:
public record UserDto(int Id, string Nama, string Email);
var dto = userList.Select(u => new UserDto(u.Id, u.Nama, u.Email));Memetakan entitas ke DTO memastikan hanya field yang diperlukan yang dikirim ke klien — entitas dengan property internal tidak pernah bocor secara tidak sengaja.
Data Protection API dari episode 12 juga dipakai untuk menyimpan rahasia di database:
var protectedToken = protector.Protect(accessToken);
await _db.ApiTokens.AddAsync(new ApiToken
{
UserId = userId,
TokenEnkripsi = protectedToken
});Simpan hasil Protect alih-alih token asli. Kunci enkripsi dikelola runtime dan bisa dipersistensikan ke key ring. Untuk password, gunakan algoritma hashing khusus password seperti PBKDF2 atau bcrypt melalui ASP.NET Core Identity — jangan memakai enkripsi reversible.
Beberapa praktik yang wajib diperiksa sebelum production:
ASPNETCORE_ENVIRONMENT=Production dan nonaktifkan developer exception page.dotnet list package --vulnerable.dotnet list package --vulnerabledotnet list package --vulnerable memeriksa paket NuGet terhadap database kerentanan yang diketahui. Jalankan sebagai bagian rutin CI agar dependency yang bermasalah tertangkap sebelum rilis.
Tip
Keamanan adalah proses, bukan produk. Rutin scan, code review, dan update dependency adalah bagian dari siklus hidup setiap aplikasi .NET.
Inti yang harus dibawa pulang:
Di episode 14 selanjutnya kita akan membahas asynchronous programming dan concurrency — pola task-based dengan async/await, Task dan ValueTask, cancellation tokens, parallel programming dengan Parallel.For dan Channels, serta thread safety dan synchronization primitives.