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
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
- Route yang TIDAK di bawah router manapun dengan auth middleware (misal endpoint publik seperti health-check) tetap
auth_protected: false — tidak over-detect
- Test regression: app.use()/server.use() global middleware masih terdeteksi seperti sebelumnya (tidak regresi)
- Minimal 1 unit test baru yang reproduce pattern
routerVar.use(middlewareName) + routes didaftarkan di router yang sama
Checklist Laporan Worker
Mengapa
Ditemukan saat audit
api-mapterhadap codebase Express nyata (Coretax-Auto-Downloader, vps-deploy/api/kds). Output menunjukkanauth_protected: 3dari totaltotal_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()discripts/apimap_engine.py(baris ~726) regex-nya HARDCODE hanya kenali receiverapp/server/fastify/hono: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 viarouter.use(authMiddleware)dilaporkan sebagaiauth_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-mapdipakai untuk audit permukaan API — salah satu use case utamanya adalah cek endpoint mana yang tidak terproteksi. Fieldauth_protectedjadi tidak reliable untuk hampir semua backend Express yang pakaiRouter()modular (pattern paling umum di Express modern), bukan monolithicapp.get/postsemua di satu file.Tujuan
api-mapharus benar mendeteksi middleware yang di-attach ke instanceRouter()custom (bukan cumaapp/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
accountingRouter.use(authMiddleware)HANYA berlaku untuk route yang didaftarkan viaaccountingRouter.get/post/put/delete(...)— BUKAN untuk instance router lain di file berbeda. Jangan buat semua route auth_protected secara serampangan.= Router()atau= express.Router()assignment, lalu lacak semua.use()dan.get/post/put/delete()call pada variable yang sama.app.use()/server.use()global middleware — itu harus tetap terdeteksi seperti sebelumnya._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
api-map <kds-workspace>menunjukkanauth_protectedcount 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(...))sejenisauth_protected: false— tidak over-detectrouterVar.use(middlewareName)+ routes didaftarkan di router yang samaChecklist Laporan Worker