Skip to content

fix(api): /api/info/deployment is authenticated but books zero API-key usage (regression from #1523) #156

Description

@cristim

Summary

GET /api/info/deployment is an authenticated route that now books zero API-key usage. It booked 1 before LeanerCloud/cloud-commitments-cli#1523. Every authenticated request to it is invisible to the per-key usage stats that LeanerCloud/cloud-commitments-cli#1523 exists to surface.

Found by adversarial review of LeanerCloud/cloud-commitments-cli#1523, after that PR had merged (a233ce0c4). Not a security issue — the route is still genuinely authenticated. A counting defect only.

Mechanism

validateSecurityContext early-returns on isPublicEndpoint(path) before the booking block:

  • handler.go:642 — early return for a public endpoint
  • handler.go:661 — the usage booking

isPublicEndpoint prefix-matches "/api/info" (middleware.go:22), but /api/info/deployment is registered AuthUser (router.go:363). So the request skips the booking block, and is then authenticated by a different path — Router.Route → h.requireAuth → authenticatePrincipal — which books nothing.

Before LeanerCloud/cloud-commitments-cli#1523 the booking lived inside ValidateUserAPIKey, so it fired on that path too. Moving the booking to validateSecurityContext was the correct fix for the 2x-5x overcount, but it left this one route behind the early return.

Verification

All 119 routes were enumerated and cross-checked against isPublicEndpoint. This is the only affected route (publicButAuthed=1, authPublicNotInPublicList=0).

Measured three ways, including against the merge commit on main:

PR head      /api/info/deployment       status=200 validations=1 totalUsageBooked=0
pre-fix      /api/info/deployment       status=200 validations=1 totalUsageBooked=1
origin/main  (a233ce0c4)                status=200 validations=1 totalUsageBooked=0
control      /api/api-keys/usage-stats  status=200 validations=2 totalUsageBooked=1

Disproved: this is not an auth bypass

Tested explicitly. Without a credential, /api/info/deployment returns 401 {"error":"authentication required"} — requireAuth genuinely holds. The prefix overlap is also pre-existing, introduced by LeanerCloud/cloud-commitments-cli#796 (cbdc4be2c) which deliberately moved deployment info behind auth; LeanerCloud/cloud-commitments-cli#1523 touched neither router.go's info routes nor isPublicEndpoint.

Suggested fix

Move "/api/info" from the prefix list into the exact-match switch in isPublicEndpoint. That closes the under-count and the middleware-shadowing together, and is smaller than relocating the booking.

Test guidance

The existing requireExactlyOneBooking helper does catch booking-zero — it opens with a positive wait that fails with "no API key usage reached the store". It only covers the two routes it exercises, which is exactly why this slipped through. A regression test should assert exactly-one booking on /api/info/deployment specifically, since it is the only route where the public-prefix and authenticated-route sets overlap.

Related, out of scope

Handler.authenticate and checkUserAPIKey are confirmed vestigial — no production callers, only tests. They call ValidateUserAPIKeyAPI, so pre-LeanerCloud/cloud-commitments-cli#1523 they booked usage and now do not; harmless precisely because they are dead. Worth removing separately.

No activity

Activity on this issue will appear here.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions