myxce/.wolf/bugs/bug-1949.md
Rongsong Shen 19be145d6f
docs(buglog): record Gitea sync for bug-1936..bug-1957
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-10 10:14:39 +00:00

3.2 KiB

id status status_updated status_note component severity timestamp last_seen occurrences files tags related fix_commits gitea_issue gitea_synced_status gitea_synced_hash
bug-1949 fixed 2026-10-10 apiserver security 2026-10-10T08:15:09Z 2026-10-10T08:15:09Z 1
src/frontend/apiserver/controllers/rbac_check.go
src/frontend/apiserver/middleware/whitelist.go
src/frontend/apiserver/controllers/response.go
apiserver
security
middleware
42a402a5
380 fixed 660a9d0500d6

bug-1949: apiserver RequirePermission and IP whitelist write an error but do not abort the request

Description

Observed: (source reading, .kiro/reviews/project-gap-review-2026-10-10.md (P0); to be confirmed by a failing test before the fix) On a bad token RequirePermission returns an error response without Abort() (controllers/rbac_check.go:119-122); the IP whitelist does the same for an invalid client IP (middleware/whitelist.go:130-132); ReturnError never aborts (controllers/response.go:30-37).

Expected: A failed middleware check stops the request before the handler runs. Impact: Security: the handler may still run after an authorization failure. Found by: review: .kiro/reviews/project-gap-review-2026-10-10.md (P0)

Environment

  • OS: no /etc/os-release; Docker container; NixOS kernel; kernel Linux 6.18.33 x86_64
  • libc: glibc 2.42-47 (interpreter /nix/store/wb6rhpznjfczwlwx23zmdrrw74bayxw4-glibc-2.42-47/lib/ld-linux-x86-64.so.2)
  • Toolchain: gcc (GCC) 15.2.0, meson 1.9.1
  • Build: asan (xce.build)
  • Code: scheduler-framework @ 94472ee3-dirty
  • Deployment: any (found by source reading; the failing test that confirms it is named in Verification)

Reproduction

  1. Call a RequirePermission-guarded route with a malformed token claim (see the code path above) and observe the handler running.
  • Frequency: deterministic (by code reading; confirmed by the RED test of the fix)
  • Evidence: the code sites quoted in Description; no logs kept.

Root cause

RequirePermission (controllers/rbac_check.go) and WhitelistIPMiddleware (middleware/whitelist.go) wrote an error via ReturnError without ctx.Abort().

Fix

ctx.Abort() added at both sites and on ValidateHandler's request-body check; a bad token in RequirePermission now answers 401 (was 500). ReturnError stays non-aborting (documented): hosts.go relies on ctx.IsAborted() after a helper's error. Follow-up: ControlHost can still write twice if reached.

Verification

  • Test: TestRequirePermission_AbortsOnInvalidToken (controllers/rbac_abort_test.go): RED handler ran after RequirePermission failed (status 500); TestWhitelistIPMiddleware_AbortsOnFailure/unparsable_client_IP: RED handler ran after the IP whitelist rejected; GREEN after.
  • Suites: xce-build.sh all asan xce.build --incremental on the merged branch, 2026-10-10: all C suites Ok 155 / Fail 0, frontend Go unit tests ok, xceadmin tests ok; apiserver CGO_ENABLED=0 go test ./... (incl. middleware, router, cmd) ok
  • Live: n/a: unit/fixture-level verification only; no live deployment was run (follow-up)

References

  • Fix commit: 42a402a5 (on scheduler-framework; worker-branch original in the merge)
  • Review: .kiro/reviews/project-gap-review-2026-10-10.md