Files
Redflag/docs/A3_PreFix_Tests.md
jpetree331 ee246771dc test(security): A-3 pre-fix tests for auth middleware coverage bugs
Pre-fix test suite documenting 8 auth middleware bugs found during
the A-3 recon audit. Tests are written to FAIL where they assert
correct post-fix behavior, and PASS where they document current
buggy behavior. No bugs are fixed in this commit.

Tests added:
- F-A3-11 CRITICAL: WebAuthMiddleware leaks JWT secret to stdout
  (3 tests: secret in output, emoji in output, ETHOS format)
- F-A3-7 CRITICAL: Config download requires no auth (2 tests)
- F-A3-6 HIGH: Update package download requires no auth (2 tests)
- F-A3-10 HIGH: Scheduler stats accepts agent JWT (2 tests)
- F-A3-12 MEDIUM: Cross-type JWT token confusion (2 tests)
- F-A3-2 MEDIUM: /auth/verify dead endpoint (2 tests)
- F-A3-13 LOW: RequireAdmin middleware missing (1 test + 1 build-tagged)
- F-A3-9 MEDIUM: Agent self-unregister no rate limit (2 tests)

Current state: 10 FAIL, 7 PASS, 1 SKIP (build-tagged), 1 unchanged
See docs/A3_PreFix_Tests.md for full inventory.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 21:54:48 -04:00

10 KiB

A-3 Pre-Fix Test Suite

Date: 2026-03-28 Branch: culurien Purpose: Document auth middleware coverage bugs BEFORE fixes are applied. Reference: A-3 Auth Middleware Audit (recon findings F-A3-1 through F-A3-14)

These tests prove that the bugs exist today and will prove the fixes work when applied. Do NOT modify these tests before the fix is ready — they are the regression baseline.


Test Files Created

File Package Bugs Documented
aggregator-server/internal/api/middleware/auth_secret_leak_test.go middleware_test F-A3-11 (agent-side baseline)
aggregator-server/internal/api/handlers/auth_middleware_leak_test.go handlers_test F-A3-11 (web middleware leak)
aggregator-server/internal/api/handlers/downloads_auth_test.go handlers_test F-A3-7, F-A3-6
aggregator-server/internal/api/middleware/scheduler_auth_test.go middleware_test F-A3-10
aggregator-server/internal/api/middleware/token_confusion_test.go middleware_test F-A3-12
aggregator-server/internal/api/handlers/auth_verify_test.go handlers_test F-A3-2
aggregator-server/internal/api/middleware/require_admin_test.go middleware_test F-A3-13
aggregator-server/internal/api/middleware/require_admin_behavior_test.go middleware_test F-A3-13 (build-tagged, cannot compile yet)
aggregator-server/internal/api/handlers/agent_unregister_test.go handlers_test F-A3-9

How to Run

# Middleware tests (scheduler, token confusion, RequireAdmin, agent auth)
cd aggregator-server && go test ./internal/api/middleware/... -v

# Handler tests (JWT leak, downloads auth, verify, unregister)
cd aggregator-server && go test ./internal/api/handlers/... -v

# Run specific test groups
cd aggregator-server && go test ./internal/api/middleware/... -v -run TestScheduler
cd aggregator-server && go test ./internal/api/middleware/... -v -run TestToken
cd aggregator-server && go test ./internal/api/middleware/... -v -run TestRequireAdmin
cd aggregator-server && go test ./internal/api/handlers/... -v -run TestWebAuth
cd aggregator-server && go test ./internal/api/handlers/... -v -run TestConfigDownload
cd aggregator-server && go test ./internal/api/handlers/... -v -run TestAuthVerify

Test Inventory

File 1: middleware/auth_secret_leak_test.go — Agent Middleware Baseline

TestAgentAuthMiddlewareDoesNotLogSecret

  • Bug: F-A3-11 (baseline contrast — agent middleware is clean)
  • Asserts: Agent AuthMiddleware does NOT print JWT secret to stdout
  • Current state: PASS (agent middleware is not affected)
  • Purpose: Establishes that the leak is specific to WebAuthMiddleware

TestAgentAuthMiddlewareLogHasNoEmoji

  • Bug: F-A3-11 (baseline contrast)
  • Asserts: Agent AuthMiddleware stdout has no emoji characters
  • Current state: PASS

File 2: handlers/auth_middleware_leak_test.go — WebAuth Secret Leak

TestWebAuthMiddlewareDoesNotLogSecret

  • Bug: F-A3-11 CRITICAL
  • Asserts: WebAuthMiddleware stdout does NOT contain the JWT secret string
  • Current state: FAIL — auth.go:128 prints h.jwtSecret directly
  • After fix: PASS — remove secret from log output

TestWebAuthMiddlewareLogFormatHasNoEmoji

  • Bug: F-A3-11 CRITICAL
  • Asserts: WebAuthMiddleware stdout has no emoji (specifically U+1F513), word "secret" absent
  • Current state: FAIL — output contains lock emoji and word "secret"
  • After fix: PASS — use [WARNING] [server] [auth] format

TestWebAuthMiddlewareLogFormatCompliant

  • Bug: F-A3-11 CRITICAL
  • Asserts: If stdout output exists, lines start with [TAG] pattern, no secret in output
  • Current state: FAIL — output is emoji-prefixed, contains secret
  • After fix: PASS — ETHOS-compliant format or no stdout output

File 3: handlers/downloads_auth_test.go — Unauthenticated Downloads

TestConfigDownloadRequiresAuth

  • Bug: F-A3-7 CRITICAL
  • Asserts: GET /downloads/config/:agent_id returns 401/403 without auth
  • Current state: FAIL — returns 200 (no auth middleware on route)
  • After fix: PASS — add AuthMiddleware or WebAuthMiddleware

TestConfigDownloadCurrentlyUnauthenticated

  • Bug: F-A3-7 CRITICAL
  • Asserts: Config download succeeds without auth (documents bug)
  • Current state: PASS — no auth middleware, request reaches handler
  • After fix: FAIL — update to assert 401

TestUpdatePackageDownloadRequiresAuth

  • Bug: F-A3-6 HIGH
  • Asserts: GET /downloads/updates/:package_id returns 401/403 without auth
  • Current state: FAIL — returns 200 (no auth middleware)
  • After fix: PASS — add AuthMiddleware

TestUpdatePackageDownloadCurrentlyUnauthenticated

  • Bug: F-A3-6 HIGH
  • Asserts: Update package download succeeds without auth (documents bug)
  • Current state: PASS
  • After fix: FAIL — update to assert 401

File 4: middleware/scheduler_auth_test.go — Scheduler Wrong Auth

TestSchedulerStatsRequiresAdminAuth

  • Bug: F-A3-10 HIGH
  • Asserts: Agent JWT is rejected on /scheduler/stats (should require admin)
  • Current state: FAIL — agent JWT accepted (200)
  • After fix: PASS — change to WebAuthMiddleware

TestSchedulerStatsCurrentlyAcceptsAgentJWT

  • Bug: F-A3-10 HIGH
  • Asserts: Agent JWT is accepted on /scheduler/stats (documents bug)
  • Current state: PASS — AuthMiddleware accepts agent JWT
  • After fix: FAIL — update to assert rejection

File 5: middleware/token_confusion_test.go — Cross-Type Token Confusion

TestWebTokenRejectedByAgentAuthMiddleware

  • Bug: F-A3-12 MEDIUM
  • Asserts: Web/admin JWT is rejected by agent AuthMiddleware
  • Current state: FAIL — web JWT passes agent auth (shared secret, no audience check)
  • After fix: PASS — add issuer/audience claims or separate secrets

TestAgentTokenRejectedByWebAuthMiddleware

  • Bug: F-A3-12 MEDIUM
  • Asserts: Agent JWT is rejected by WebAuthMiddleware
  • Current state: FAIL — agent JWT passes web auth (shared secret, claims parse succeeds)
  • After fix: PASS — add issuer/audience claims or separate secrets

File 6: handlers/auth_verify_test.go — Dead Verify Endpoint

TestAuthVerifyAlwaysReturns401WithoutMiddleware

  • Bug: F-A3-2 MEDIUM
  • Asserts: /auth/verify returns 401 even with valid JWT (no middleware sets context)
  • Current state: PASS — documents the dead endpoint
  • After fix: N/A (test documents pre-fix state)

TestAuthVerifyWorksWithMiddleware

  • Bug: F-A3-2 MEDIUM
  • Asserts: /auth/verify returns 200 when WebAuthMiddleware is applied
  • Current state: PASS — demonstrates the fix is just adding middleware to the route
  • Note: This test already passes because it applies WebAuthMiddleware directly. The bug is in the route registration (main.go:388), not in the handler code.

File 7: middleware/require_admin_test.go — Missing RequireAdmin

TestRequireAdminMiddlewareExists

  • Bug: F-A3-13 LOW
  • Asserts: RequireAdmin function exists in middleware package (AST scan)
  • Current state: FAIL — function not found
  • After fix: PASS — implement RequireAdmin()

File 8: middleware/require_admin_behavior_test.go — RequireAdmin Behavior

  • Build tag: //go:build ignore — cannot compile until RequireAdmin exists
  • Bug: F-A3-13 LOW
  • Contains: TestRequireAdminBlocksNonAdminUsers — tests admin vs non-admin role check
  • Current state: Cannot compile (skipped)
  • After fix: Remove build tag, test should PASS

File 9: handlers/agent_unregister_test.go — Missing Rate Limit

TestAgentSelfUnregisterHasNoRateLimit

  • Bug: F-A3-9 MEDIUM
  • Asserts: Documents that DELETE /:id route has no rate limiter
  • Current state: PASS — documents the bug

TestAgentSelfUnregisterShouldHaveRateLimit

  • Bug: F-A3-9 MEDIUM
  • Asserts: DELETE /:id SHOULD have rate limiter in middleware chain
  • Current state: FAIL — no rate limiter on route
  • After fix: PASS — add rate limiter

State-Change Summary

Test Current After Fix
TestAgentAuthMiddlewareDoesNotLogSecret PASS PASS (unchanged)
TestAgentAuthMiddlewareLogHasNoEmoji PASS PASS (unchanged)
TestWebAuthMiddlewareDoesNotLogSecret FAIL PASS
TestWebAuthMiddlewareLogFormatHasNoEmoji FAIL PASS
TestWebAuthMiddlewareLogFormatCompliant FAIL PASS
TestConfigDownloadRequiresAuth FAIL PASS
TestConfigDownloadCurrentlyUnauthenticated PASS FAIL (update)
TestUpdatePackageDownloadRequiresAuth FAIL PASS
TestUpdatePackageDownloadCurrentlyUnauthenticated PASS FAIL (update)
TestSchedulerStatsRequiresAdminAuth FAIL PASS
TestSchedulerStatsCurrentlyAcceptsAgentJWT PASS FAIL (update)
TestWebTokenRejectedByAgentAuthMiddleware FAIL PASS
TestAgentTokenRejectedByWebAuthMiddleware FAIL PASS
TestAuthVerifyAlwaysReturns401WithoutMiddleware PASS PASS (unchanged)
TestAuthVerifyWorksWithMiddleware PASS PASS (unchanged)
TestRequireAdminMiddlewareExists FAIL PASS
TestRequireAdminBlocksNonAdminUsers SKIP (build tag) PASS
TestAgentSelfUnregisterHasNoRateLimit PASS PASS (unchanged)
TestAgentSelfUnregisterShouldHaveRateLimit FAIL PASS

Bold FAIL = tests that assert correct post-fix behavior (will flip to PASS after fix). Regular PASS = tests that document current buggy state (some will flip to FAIL after fix).


Notes

  1. TestAuthVerifyWorksWithMiddleware passes even in pre-fix state because it directly applies WebAuthMiddleware to the test router. The bug is not in the handler but in the route registration (main.go:388 missing middleware). This test validates that the fix is a one-line change.

  2. TestAgentTokenRejectedByWebAuthMiddleware reveals that JWT cross-type confusion works in BOTH directions: agent tokens pass web auth AND web tokens pass agent auth. The jwt.ParseWithClaims call succeeds because both claim types share the same signing key and the JSON unmarshaling is permissive.

  3. require_admin_behavior_test.go uses //go:build ignore because it references middleware.RequireAdmin which does not exist. Enable this test when F-A3-13 is fixed by removing the build tag.

  4. All A-2 tests continue to pass (no regressions from A-3 test additions).