Skip to main content

Content Service — Keamanan & Hardening

Port: 8090 | DB: db_kesles_merchant_content | Status: LIVE

Keamanan & Hardening

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

Auth & Authorization

  • Validasi expiry token wajib: parseJWTSubject menggunakan jwt.WithExpirationRequired() sehingga token yang tidak memiliki klaim exp selalu ditolak — tidak ada jalur di mana token tak-berumur bisa diterima sebagai sesi valid.
  • Validasi issuer token: parseJWTSubject menggunakan jwt.WithIssuer("kesles-merchant-auth") sehingga token HS256 dari sistem lain yang kebetulan berbagi secret yang sama (misal environment staging atau sistem terpisah) otomatis ditolak di production content_service.

Keandalan Lapisan Data

  • Existence check fail-safe: ArticleExists di store.go mengembalikan error (bukan true) ketika koneksi database nil — misconfiguration DB tidak bisa mem-bypass logika keberadaan artikel, dan operasi downstream tidak berjalan dalam keadaan data yang tidak terverifikasi.

Response Headers & Middleware

  • Security headers lengkap: Service menyertakan Content-Security-Policy: default-src 'none', Strict-Transport-Security: max-age=63072000; includeSubDomains, dan Permissions-Policy: camera=(), microphone=(), geolocation=() pada setiap response HTTP.
  • Panic recovery middleware: Mux dibungkus withSecurityHeaders(withObservability(withRecovery(mux))) — handler panic tidak menjatuhkan goroutine tanpa response; server mengembalikan HTTP 500 dan melanjutkan melayani request lain. Content_service menjadi referensi pattern ini untuk service lain di codebase.

Rate Limiting & Resource Management

  • Rate limiting pada public endpoints: Endpoint /public/umkm-academy/* dilindungi publicLimiter (120 req/menit per IP). Middleware withPublicRateLimit di-wrap bersama withPublicCache(300s) di semua 4 public routes — akses tidak terbatas tidak dimungkinkan, scraping berat atau flood attack pada konten publik tidak dapat menguras DB connection pool.

  • Goroutine cleanup rate limiter dapat di-stop saat shutdown: Rate limiter cleanup goroutine menggunakan stop chan struct{} dan time.NewTicker — goroutine mematuhi sinyal shutdown. Server.Shutdown() memanggil module.Shutdown() yang menutup stop channel di semua 3 limiter. Tidak ada goroutine orphan pada graceful shutdown atau saat test suite dijalankan berulang.