Blog
Catatan teknis seputar web development, DevOps, dan integrasi AI.
500 artikel
- 01.30security
Menjaga Isi, Bukan Wadah: Guard Dua Arah Rebind Media
Guard menjaga entitas tujuan tetapi melewatkan id media sumber; setelah rebind, mengelola media orang lain jadi sah. Perbaikannya: guard sebelum mutasi.
TL;DR: Jadi ada editor yang bisa "mencuri" media punya entitas lain pas rebind galeri, soalnya endpoint cuma ngecek tujuan, nggak cek asal media-nya. Perbaikannya: tiap media dicek kepemilikan modulnya dalam satu kueri, ditolak 403 sebelum nulis apa-apa, plus uji regresi merah-hijau. Modul pengumuman juga ketahuan kena celah serupa, jadi penjagaan cakupan wajib dipanggil di semua jalur tulis.
#security#rbac#idor - 01.30database
Membalik Default Kolom: Saklar Perilaku untuk Baris Baru
Mengubah DEFAULT satu kolom tercatat instan dan hanya menyentuh metadata. Yang perlu disiapkan justru jalur-jalur INSERT yang tidak ikut berubah.
TL;DR: Jadi waktu itu fitur ulasan entitas baru nyala terus, padahal pengembangnya maunya mati dulu. Fixnya gampang banget: satu baris ALTER TABLE buat ubah default kolom rating_enabled jadi 0. Aman pas produksi karena cuma ubah metadata, data lama nggak disentuh, plus ada tes integrasi buat ngunci perilakunya.
#mysql#database-migration#schema - 00.15security
Implementasi Jejak Audit Best Effort pada CMS KotaPortal
Tabel audit_logs append-only ditulis setelah mutasi sukses, tahan penghapusan akun, dan tidak pernah menggagalkan request bisnis.
TL;DR: Audit trail di CMS itu penting karena cuma andelin kolom updated_at, jadi nggak jelas siapa yang ubah data. Solusinya bikin tabel audit_logs append-only yang dicatet tiap kali mutasi sukses, tanpa foreign key ke tabel user biar jejaknya tetap kebaca walau akun dihapus. Best effort banget, gagal nulis log cuma jadi warning, nggak bikin aplikasi tumbang.
#audit-log#go#mysql - 00.14security
Penyamaan Enum dan Slug pada Gerbang Modul di CMS KotaPortal
Gerbang moderasi yang selalu tertutup bukan karena otorisasi rusak, tetapi karena enum modul tidak pernah dipetakan ke slug konten.
TL;DR: Jadi masalah lencana read-only di daftar moderasi itu bukan karena permission service rusak, tapi frontend kirim enum huruf besar kayak PARIWISATA padahal backend nyari slug kayak wisata, jadi gagal diam-diam deh. Solusinya dibikin mapping MODULE_TO_SLUG biar enum diubah jadi slug yang bener. Sisi server juga dikasih guardModule yang ngecek kepemilikan dulu, kalau gagal ya langsung 403.
#rbac#typescript#authorization - 00.13security
Keputusan ZAP di Baris Selesai
Papan selesai kini menuntut satu token keputusan ZAP per baris: rescan dengan path bukti atau none dengan alasan tertulis.
TL;DR: Jadi begini, nge-scan pasif ZAP berulang buat tiap kartu selesai itu nggak ngebuktiin apa-apa. Solusinya, board validator sekarang mewajibkan token keputusan: ZAP:rescan plus path laporan, atau ZAP:none plus alasan tertulis. Hasilnya, utang keamanan jadi kelihatan, bisa ditrack, dan review fokus ngecek isi keputusan, bukan scan yang hasilnya sama terus.
#security#owasp#zap - 23.29backend
Dua Himpunan: Yang Boleh Dibaca, Yang Boleh Dikelola
Membuka akses baca lintas bidang tanpa melonggarkan tulis: readable set dan manageable set sebagai dua himpunan terpisah yang fail-closed.
TL;DR: Dulu API KotaPortal salah kaprah, nyetarain hak baca sama tulis jadi satu, makanya bidang lain cuma lihat daftar kosong. Sekarang dipisah jadi ModulesFor buat nulis dan ReadableModules buat baca semua, jadi ?module= cuma filter, bukan gate. Fail-closed tetap ada buat bidang tak dikenal, UI tetap satu navigasi, tombol edit aja yang disembunyiin.
#rbac#golang#http - 23.28security
Body Error yang Mengulang Input Anda
Pesan kesalahan API yang memantulkan nilai input pengirim adalah kanal rekonesans murah. Pola perbaikan: kode spesifik, detail statis.
TL;DR: Jadi API admin KotaPortal ternyata mantulin input user di pesan error, jadi deh jalan tol buat nyoba injeksi. Fixnya gampang: kode error dibikin statis kayak FORBIDDEN, interpolasi inputnya dibuang semua. Terus tiap endpoint dikasih tes regresi pake nilai probe, kalau masih muncul di body respons berarti belum beres.
#api#security#http - 23.28backend
CRUD Paket Sewa yang Tahu Scope-nya
Modul CRUD paket sewa dengan scope bidang: fail-closed lewat pasangan sentinel nil dan slice kosong, lima domain error, satu mapError.
TL;DR: Jadi gini, di KotaPortal staf cuma boleh utak-atik paket sesuai modul departemen mereka, kalau kategorinya NULL berarti lintas departemen dan cuma aktor global yang boleh. Alih-alih nyebar if di mana-mana, kontrak scope dipusatkan di service layer pakai lima error yang diterjemahin mapError ke kode HTTP. Trik kuncinya: nil artinya tanpa filter, slice kosong artinya deny-all, jadi query gagal aman.
#golang#rbac#http - 13.51frontend
Tanggal yang Bergeser Sendiri: Pin Zona Waktu Saat Render
Data benar, tampilan salah: toLocaleString tanpa timeZone membuat server UTC dan browser WIB merender tanggal berbeda. Kunci di lapisan presentasi.
TL;DR: Tanggal tiket kelihatan beda karena toLocaleString dipanggil tanpa opsi timeZone, jadi hasilnya ngikutin zona server. Data UTC-nya aman, cuma lapisan tampilan yang salah render saat hydration di browser WIB. Solusinya pakai satu utilitas formatDateTime yang mengunci Asia/Jakarta, terus dibungkus test biar gak balik lagi.
#frontend#nextjs#timezone