1.5 KiB
1.5 KiB
Phase 4 — Surface C: terminal
~2 days. First surface accepting user input — injection (A03) is the primary risk here.
RED
exec_parse_test.go— fuzz corpus: every non-allowlisted input rejects and performs zero upstream callsexec_test.go— unknown namespace rejects on snapshot membership, not regexterminal.e2e.ts(Playwright, hard requirement) — load terminal UI, submitget nodes, assert rendered output; submit an injection payload, assert rejection surfaces in UI, zero upstream call
GREEN
POST /api/exec— session cookie, 20/min/session; input parses to a closed command enum, anything unmatched rejected before any lookup- Command set:
get nodes,get pods <ns>,get apps,top nodes,describe pod <ns> <name>,help - Namespace and resource-name arguments validated by set membership against current snapshot, not regex/escaping
- No shell, no
exec, nokubectlbinary in the container image - Frontend: reuse components/InteractiveTerminal.tsx, wire to
/api/exec - Structured logging: every rejected
/api/execinput logged
REFACTOR
simplifypass on the enum parser
Verify
# attempt injection payloads against /api/exec; all rejected, all logged
curl -X POST https://riotpiao.com/api/exec -d '{"cmd":"get pods; rm -rf /"}'
pnpm test:e2e terminal.e2e.ts # required, must pass before merge
Next: 06-phase5-chat.md