Lewati ke konten utama

Keamanan payment_service

Port: 8085 | DB: db_kesles_merchant_payment | Status: LIVE

Dokumen ini mencatat keunggulan keamanan yang telah diimplementasikan dan diverifikasi pada payment_service.

Keamanan & Hardening

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


Authentication & Otorisasi

  • JWT dengan validasi ekspirasi dan issuer wajib: Parser JWT menggunakan jwt.NewParser dengan opsi WithExpirationRequired() dan WithIssuer(issuer) secara bersamaan. Token yang tidak memiliki klaim exp ditolak sepenuhnya — tidak ada token yang valid selamanya. Klaim issuer dicocokkan dengan nilai konfigurasi JWTIssuer (default "kesles-merchant-auth"), sehingga token dari service atau environment lain tidak dapat digunakan ulang untuk melewati autentikasi (cross-service token replay dicegah).

  • Konfigurasi INTERNAL_API_KEY tahan whitespace-only: LoadConfig melakukan strings.TrimSpace pada nilai InternalAPIKey sebelum pengecekan kosong. Key yang hanya berisi spasi atau karakter whitespace diperlakukan sebagai tidak valid dan menyebabkan service gagal saat startup (fail-fast). Ini mencegah skenario fail-open di mana key terlihat terisi padahal kosong secara fungsional.


Keamanan PSP & IP Allowlist

  • X-Forwarded-For hanya dipercaya dari trusted proxy: Fungsi extractRemoteIP hanya membaca header X-Forwarded-For apabila remoteIP hasil parse dari r.RemoteAddr adalah loopback address (yaitu, request datang dari nginx di host yang sama). Request yang datang langsung dari luar tidak dapat memanipulasi header X-Forwarded-For untuk memalsukan IP dan melewati IP allowlist PSP — bypass injection dari luar jaringan dicegah sepenuhnya.

  • Validasi refund berlapis untuk mencegah over-refund dan IDOR: Handler refund (internal maupun merchant-facing) melakukan pre-validasi jumlah sebelum InsertRefund dieksekusi. Validasi mencakup: (1) pengecekan amount <= gross_amount - sum(approved_refunds) untuk memastikan akumulasi refund tidak melebihi transaksi asal, dan (2) verifikasi kepemilikan melalui GetTransactionBasicInfo yang mengonfirmasi bahwa original_transaction_id benar-benar milik merchantID pemohon. Ini mencegah over-refund dan serangan IDOR di mana merchant A mereferensikan transaksi merchant B.


Integritas Data & Keandalan

  • Reconcile settlement dalam transaksi atomik: Fungsi reconcileMarkCompleted menggunakan SELECT ... FOR UPDATE di dalam satu database transaction untuk mengunci baris sebelum memperbarui status. PSP webhook yang dikirim terlambat (retry) tidak dapat mereset status transaksi dari completed kembali ke pending karena status sudah terkunci dan divalidasi sebelum update diizinkan.

  • Respons HTTP 500 untuk infrastructure failure pada PSP webhook: Handler handlePSPEvents mengembalikan HTTP 500 saat processingStatus bernilai failed akibat kegagalan infrastruktur (database error, timeout, dsb.). Ini memaksa PSP melakukan retry secara otomatis sesuai kontrak protokol. HTTP 200 hanya dikembalikan untuk skenario sukses atau business-logic error yang memang tidak perlu di-retry (misalnya transaksi duplikat yang sudah diproses).

  • Pembatasan ukuran body request di seluruh handler: Middleware withBodyLimit membatasi ukuran request body maksimum 4 MB dan dibungkus di level tertinggi via loggingMiddleware(withBodyLimit(mux)). Seluruh handler POST dan PATCH terlindungi secara otomatis — tidak ada handler yang dapat menerima payload berukuran tak terbatas, sehingga risiko memory exhaustion akibat request body besar dieliminasi.


Referensi Audit

Seluruh temuan di atas berasal dari siklus audit keamanan internal Kesles Merchant yang berlangsung pada periode 2026-05-29 hingga 2026-06-05 dan telah diverifikasi fixed sebelum soak phase dimulai. Detail teknis per temuan dapat dilihat di dokumen audit internal KESLES_AUDIT_CLOSE.md.