Episode ini membahas praktik pemrograman aman: input validation dengan DataAnnotations, pencegahan serangan OWASP Top 10 pada aplikasi .NET, penyimpanan aman dengan Data Protection API, serta pencegahan SQL injection, XSS, CSRF, dan kebocoran data sensitif.

Keamanan bukan fitur yang ditambahkan di akhir — dia adalah cara berpikir yang melekat pada setiap baris kode. Kebanyakan serangan yang berhasil memanfaatkan celah yang sebenarnya mudah dicegah sejak awal.
Di episode 12 kalian mengamankan akses. Episode 13 melangkah lebih dalam: bagaimana menulis kode yang tidak punya celah sejak awal. Ini mencakup validasi input, praktik aman terhadap OWASP Top 10, penyimpanan data sensitif, dan pencegahan serangan web paling umum.
Aturan emas pertama: jangan pernah percaya input pengguna. ASP.NET Core memvalidasi model secara otomatis jika kalian mendeklarasikan aturannya dengan DataAnnotations:
public class DaftarRequest
{
[Required]
[EmailAddress]
public string Email { get; set; } = "";
[Required]
[StringLength(128, MinimumLength = 8)]
public string Password { get; set; } = "";
[Range(0, 150)]
public int Umur { get; set; }
}Karena controller diberi [ApiController], request yang tidak lolos validasi otomatis ditolak dengan status 400 sebelum method dijalankan. Validasi di sisi server ini wajib — validasi di browser hanya untuk kenyamanan, bukan keamanan.
OWASP Top 10 adalah daftar risiko keamanan web terbesar yang diperbarui berkala. Untuk aplikasi .NET, perhatikan yang paling relevan:
Sebagian besar poin di atas sudah ditangani framework jika kalian mengikuti pola yang benar, tetapi audit rutin tetap diperlukan. Selain itu, banyak celah muncul bukan dari framework, melainkan dari asumsi developer bahwa input akan selalu berperilaku baik — asumsi yang harus selalu dipertanyakan.
ASP.NET Core menyediakan Data Protection API untuk mengenkripsi data seperti cookie dan token. Data dikunci pada key ring dengan kunci yang bisa dirotasi:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDataProtection()
.PersistKeysToFileSystem(new DirectoryInfo("/var/lib/toko/keys"))
.SetApplicationName("Toko");
var app = builder.Build();
var protector = app.Services.GetRequiredService<IDataProtectionProvider>()
.CreateProtector("PesanSensitif");
var ciphertext = protector.Protect("data rahasia");
Console.WriteLine(ciphertext);CreateProtector("PesanSensitif") menghasilkan data terenkripsi yang hanya bisa dibuka aplikasi dengan key ring yang sama. Key ring dipersist ke filesystem agar bertahan saat restart — inilah yang dipakai ASP.NET Core untuk melindungi cookie autentikasi.
Penting: Data Protection API bukan pengganti untuk enkripsi data panjang seperti password atau kartu kredit. Untuk data yang harus bertahan dan bisa dibuka aplikasi lain, gunakan teknik enkripsi simetris standar seperti AES. Data Protection ditujukan untuk data sementara yang hanya dipahami aplikasi itu sendiri.
Selain enkripsi data, pastikan kanal komunikasi development juga aman. Sertifikat HTTPS lokal bisa diaktifkan dan dipercaya dengan dotnet dev-certs https --trust; perintah ini menandai sertifikat development sebagai terpercaya sehingga browser tidak lagi menampilkan peringatan. Di production, sertifikat dikelola terpisah oleh platform tempat aplikasi di-deploy, namun kebiasaan mengamankan kanal ini tetap penting di tiap lingkungan.
SQL injection terjadi saat input pengguna disambungkan mentah ke query. Di EF Core, selamanya pakai parameterized:
var aman = await db.Produk
.FromSqlInterpolated($"SELECT * FROM Produk WHERE Nama = {input}")
.ToListAsync();
var buruk = $"SELECT * FROM Produk WHERE Nama = '{input}'";FromSqlInterpolated mengubah interpolasi menjadi parameter SQL yang aman. Membangun string query secara manual seperti contoh buruk membuka celah injeksi — jika input berisi '; DROP TABLE Produk;--, query kalian bisa disalahgunakan.
Razor Pages dan MVC men-escape output HTML secara otomatis, sehingga XSS terhindar jika kalian tidak memakai @Html.Raw tanpa alasan. Untuk CSRF, framework menyediakan token anti-forgery yang harus disertakan pada form dan request yang mengubah state:
builder.Services.AddAntiforgery(o => o.HeaderName = "X-CSRF-TOKEN");Sementara itu, pastikan data sensitif tidak bocor: jangan log password atau token, dan gunakan variable environment untuk rahasia alih-alih hardcode. Kalian sudah belajar meletakkan rahasia dengan aman di episode 8.
Inti yang harus dibawa pulang:
Di episode 14 selanjutnya kita membuka tenaga penuh prosesor: asynchronous programming dan concurrency — Task-based async pattern, Parallel LINQ dan Task Parallel Library, Channel dan async streams, serta synchronization primitives dan thread safety.