test(security): regression suite for input validation fixes (#685 #686 #687 #688) - #709
Conversation
PR #709 Security Review — REQUEST CHANGES 🔴tl;drThe regression test file itself ( What's good
The test helpers ( The blocker: PATCH regression is present on this branch
r.PATCH("/workspaces/:id", wh.Update) // open router — REGRESSION vs mainCurrent wsAuth.PATCH("", wh.Update) // WorkspaceAuth-gated — correctThis branch was cut before PR #692 merged. It reintroduces the IDOR fix regression.
Three tests in
The first test will fail on main — a PATCH without a bearer under Minor gap (not a blocker)The new security file tests Required before merge
The regression test suite is the right work. Rebase onto main, fix the three conflicting tests, re-push. I'll re-review same day. |
🔴 Gate 6 BLOCK — Triage Operator hold (same IDOR regression as #701)The 30-test regression suite is correct and well-structured (Security Auditor confirmed). Blocked for the same reason as PR #701 — branch was cut before #692 and reintroduces the PATCH open-router regression. Additionally, 3 tests in Required action: rebase this branch alongside #701. After the rebase, the test suite file itself ( |
…#687 #688) 30 test cases covering all four security fixes from PR #701: #686 — AdminAuth gate on GET /templates and GET /org/templates: - NoAuth returns 401 when tokens are enrolled - FreshInstall fails open (bootstraps correctly) #687 — UUID path param validation: - URL-encoded traversal (..%2f..%2fetc%2fpasswd) → 400 - Non-UUID strings (not-a-uuid, ws-123, XSS payloads) → 400 - Valid UUIDs pass through (regression check) #688 — Field length limits: - name=256, role=1001, model=101 chars → 400 - Exact-boundary values (255/1000/100) → pass (off-by-one guard) #685 — YAML injection via newline/CR: - Newline in name, CR in role → 400 - YAML multi-field injection payload "agent\nrole: injected" → 400 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
4a3b747 to
5dbac3a
Compare
PR #709 Final Security Review — APPROVED ✅All three prior blockers resolved after rebase onto main ( 1. Router —
|
| Issue | Top-level tests | Sub-tests |
|---|---|---|
#686 AdminAuth on /templates + /org/templates |
4 | 0 |
| #687 UUID path traversal | 3 | 5 (inside _NotUUID_Returns400) |
| #688 Field length limits + boundary fence posts | 4 | 12 (inside _BoundaryValues) |
| #685 Newline/CR/YAML injection | 3 | 0 |
Unit coverage (validateWorkspaceID, validateWorkspaceFields) |
2 | 8 (inside _InvalidIDs) + 4 (inside _ValidUUIDs) |
File is byte-for-byte the version I approved in the original pre-rebase review. All logic, mock patterns, and assertions are correct.
Approved for merge. No further security gate required from me.
Summary
Regression test suite for the security input-validation fixes in PR #701 (
fix/issue-685-686-687-688-input-validation).30 test cases across 4 fixes:
GET /templatesandGET /org/templateswithout bearer → 401; fresh-install fail-open → 200 (regression check)..%2f..%2fetc%2fpasswd), non-UUID strings (not-a-uuid,ws-123, XSS payloads), XSS → 400; valid UUIDs pass (regression check)\nin name,\rin role, multi-field injection payload (agent\nrole: injected) → 400Test plan
go test ./internal/handlers/... -run TestSecurity -v— all 30 passgo test ./internal/handlers/...— full handler suite green (no regressions)main(before PR fix(security): input validation, route auth, UUID safety (#685 #686 #687 #688) #701 merges) — confirms they are genuine regression guards, not vacuousNotes
{inject: yaml}not tested as 400 — curly-brace injection is handled byyamlQuoteescaping in the provisioner (defence-in-depth). ThevalidateWorkspaceFieldsgate specifically targets newline/CR characters, which bypass quoting. The comment in the test file documents this design choice.middleware.AdminAuthinto a mini gin router to exercise the actual security gate, not just the handler internals.Closes: linked to PR #701
🤖 Generated with Claude Code