Skip to main content

Marketing Service — Keamanan & Hardening

Dokumen Internal · Security baseline · diverifikasi per audit 2026-05-29 – 2026-06-05

Dokumen ini mencatat implementasi keamanan yang aktif di services/marketing_service. Semua item di bawah telah diimplementasikan dan diverifikasi terhadap source code aktual.


Keamanan & Hardening

Semua item di bawah telah diimplementasikan dan diverifikasi per audit keamanan 2026-05-29–2026-06-05.

Autentikasi & Konfigurasi Service

  • Fail-fast pada konfigurasi kosong: LoadConfig() di config.go menghentikan proses (log.Fatal) saat startup jika INTERNAL_NOTIFICATION_API_KEY tidak di-set di production. Tidak ada endpoint internal yang bisa aktif secara diam-diam tanpa konfigurasi kunci yang benar.

  • Guard saat key middleware nil: RegisterInternal di routes.go mencatat slog.Error dan tidak mendaftarkan grup endpoint /internal/* jika internalKey bernilai nil — sehingga route operator tidak pernah aktif tanpa middleware kunci. Di production kondisi ini tidak akan tercapai karena LoadConfig() sudah log.Fatal lebih dulu saat key kosong, jadi masalah konfigurasi terdeteksi di awal startup, bukan saat request pertama datang.

Input Validation & SQL Safety

  • Parameterisasi query penuh di UpdateScheduleStatus: Fungsi UpdateScheduleStatus di store_schedules.go menggunakan positional placeholder $N dan args slice untuk semua nilai dinamis — termasuk klausa IN (...) yang dibangun dari positional params, bukan string concat. SQL injection via string concatenation tidak dimungkinkan.

  • Validasi UUID sebelum query database: Handler handlePostPromoClaim memanggil isValidUUID() untuk memvalidasi promoItemID sebelum nilai tersebut diteruskan ke query Postgres. String dengan format non-UUID (termasuk payload injection) ditolak di layer handler sebelum menyentuh database.

  • Pesan error database tidak bocor ke client: Error dari layer database di-log secara internal via structured logger; HTTP response ke client hanya mengembalikan pesan generik "operation failed". Nama tabel, nama constraint, dan detail skema internal tidak terekspos ke caller.

Reliability & Keamanan Runtime

  • Panic recovery middleware aktif: server.go membungkus mux dengan withRecovery() middleware — handler yang panic tidak lagi menyebabkan goroutine crash tanpa response. Setiap panic secara otomatis di-recover dan dikembalikan sebagai HTTP 500, mencegah denial-of-service tidak sengaja dari edge case handler.

  • Identitas audit trail divalidasi di hulu: created_by_user_id pada aksi schedule di-inject oleh dashboard_api dari session yang sudah terverifikasi ke request body (lihat catatan M-13 di schedule_handlers.go), bukan diisi bebas oleh end-user. Marketing service memvalidasi format UUID-nya sebelum disimpan, dan /internal/* hanya bisa dipanggil oleh service ber-internal-key — bukan langsung oleh end-user.

  • Batas ukuran respons halaman schedule: handleListSchedules membatasi maksimum 200 item per request. Tidak ada cara bagi caller untuk melakukan dump seluruh tabel promo_schedules dalam satu request, baik secara disengaja maupun tidak.


Referensi

  • Source service: services/marketing_service/
  • Audit sumber: merchant_docs/docs/plans/audit/KESLES_AUDIT_CLOSE.md
  • Status service: marketing-service-status.md
  • VM path: /home/enalfarid/kesles_merchant/merchant_marketing/marketing-service
  • Port: 127.0.0.1:8095 (loopback only)