Skip to content

fix(api-map): router.use() middleware not detected, causes false-negative auth_protected #214

Description

@Wolfvin

Mengapa

Ditemukan saat audit api-map terhadap codebase Express nyata (Coretax-Auto-Downloader, vps-deploy/api/kds). Output menunjukkan auth_protected: 3 dari total total_routes: 160 — rasio yang sangat mencurigakan untuk backend dengan banyak endpoint sensitif (accounting, assignments, employees, dll).

Root cause dikonfirmasi via grep: accountingRouter.use(authMiddleware); accountingRouter.use(requireOutletAccess); (src/routes/accounting.ts:44-45) — pattern Express standar untuk apply middleware ke SEMUA route di router tersebut. Tapi _extract_js_middleware() di scripts/apimap_engine.py (baris ~726) regex-nya HARDCODE hanya kenali receiver app/server/fastify/hono:

m = re.match(
    r'(?:app|server|fastify|hono)\s*\.\s*use\s*\(\s*(\w+)',
    stripped
)

Router bernama custom (accountingRouter, assignmentsRouter, dll — konvensi Express yang sangat umum untuk modular routing) tidak pernah cocok dengan regex ini. Akibatnya SEMUA route yang di-protect via router.use(authMiddleware) dilaporkan sebagai auth_protected: false — false negative yang berbahaya untuk tool security-auditing, karena bisa membuat orang percaya endpoint tidak terproteksi padahal sebenarnya terproteksi (atau sebaliknya, luput dari endpoint yang BENAR-BENAR tidak terproteksi karena signal-to-noise sudah rusak duluan).

Konteks

api-map dipakai untuk audit permukaan API — salah satu use case utamanya adalah cek endpoint mana yang tidak terproteksi. Field auth_protected jadi tidak reliable untuk hampir semua backend Express yang pakai Router() modular (pattern paling umum di Express modern), bukan monolithic app.get/post semua di satu file.

Tujuan

api-map harus benar mendeteksi middleware yang di-attach ke instance Router() custom (bukan cuma app/server/fastify/hono), dan mengasosiasikan middleware tersebut ke SEMUA route yang didaftarkan lewat instance router itu — bukan cuma yang middleware-nya langsung jadi argument di .get()/.post()/dst.

Constraint

  • Perbaikan harus scoped ke router instance yang benar. accountingRouter.use(authMiddleware) HANYA berlaku untuk route yang didaftarkan via accountingRouter.get/post/put/delete(...) — BUKAN untuk instance router lain di file berbeda. Jangan buat semua route auth_protected secara serampangan.
  • Harus bisa detect nama variable Router apapun (tidak hardcode ke pattern "Router" di nama variable) — deteksi dari = Router() atau = express.Router() assignment, lalu lacak semua .use() dan .get/post/put/delete() call pada variable yang sama.
  • Jangan regresi test yang sudah ada untuk app.use()/server.use() global middleware — itu harus tetap terdeteksi seperti sebelumnya.
  • Baca _extract_js_middleware (baris ~717) dan logic assembly middleware_chain per route (baris ~340-370) sebagai starting point, tapi investigasi mandiri — jangan asumsikan scope perbaikan hanya di situ.

Definition of Done

  1. api-map <kds-workspace> menunjukkan auth_protected count yang jauh lebih tinggi dari 3 — verifikasi manual dengan grep berapa banyak route yang benar-benar under router yang punya .use(authMiddleware) atau .use(requirePermission(...)) sejenis
  2. Route yang TIDAK di bawah router manapun dengan auth middleware (misal endpoint publik seperti health-check) tetap auth_protected: false — tidak over-detect
  3. Test regression: app.use()/server.use() global middleware masih terdeteksi seperti sebelumnya (tidak regresi)
  4. Minimal 1 unit test baru yang reproduce pattern routerVar.use(middlewareName) + routes didaftarkan di router yang sama

Checklist Laporan Worker

  • auth_protected count sebelum dan sesudah fix di KDS backend
  • Sample 3-5 route yang sekarang benar terdeteksi auth_protected, verifikasi manual via grep bahwa itu memang benar
  • Konfirmasi tidak ada over-detection (route publik yang salah kena flag auth_protected)
  • Hasil test suite lengkap

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions