SECURITY: harden local interfaces before browser actions - #52
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
The follow-up composer still renders an unsanitized raw thread ID, leaving a terminal-control injection path.
Get a fresh assessment by requesting another Copilot review.
Pull request overview
Hardens local web and terminal interfaces while adding security-focused CI, tests, and documentation.
Changes:
- Adds vulnerability scanning and HTTP security controls.
- Sanitizes terminal metadata and preserves Unicode IDs.
- Expands web, terminal, and fuzz security coverage.
File summaries
| File | Description |
|---|---|
.github/workflows/security.yml |
Adds Go and npm vulnerability scans. |
SECURITY.md |
Documents the local security model. |
README.md |
Links to security guidance. |
internal/web/server.go |
Adds headers and write timeout. |
internal/web/security_test.go |
Tests authentication, headers, and SSE timeout. |
web/tests/browser.spec.ts |
Tests inert rendering of malicious content. |
internal/ui/terminal_text.go |
Adds terminal label sanitization. |
internal/ui/terminal_text_test.go |
Tests terminal-control removal. |
internal/ui/monitor.go |
Sanitizes paths and Unicode-safe IDs. |
internal/ui/monitor_detail.go |
Sanitizes detailed metadata. |
internal/ui/monitor_context.go |
Sanitizes compact metadata. |
internal/ui/monitor_context_modes.go |
Sanitizes expanded metadata. |
internal/codex/session_context_security_test.go |
Adds sanitizer fuzz properties. |
Review details
- Files reviewed: 13/13 changed files
- Comments generated: 1
- Review effort level: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
🔵 Needs a closer look
Security regression tests do not fully lock down the added permission directives, timeout values, and command sanitization path.
Review details
Suppressed comments (3)
Previously missed (2) — in code that hasn't changed since the last review.
internal/ui/terminal_text_test.go:35
- The malicious
CommandDetailsvalue is never rendered becausecontextTestModelleaves this preview asSessionContextReply, while command details are displayed only for approvals. Consequently, removing command sanitization would not fail this test; append an approval-detail render while retaining the reply render that exercises the composer.
internal/web/security_test.go:21 - The security-header helper only checks
camera=(), so deleting the newly promised microphone, geolocation, payment, or USB restrictions would leave this regression suite green. Assert the complete Permissions-Policy value so every added restriction is protected.
This issue also appears on line 102 of the same file.
internal/web/security_test.go:102
- This check only proves each timeout is nonzero, not the documented 5s/10s/15s/30s security bounds. A change to an ineffective duration (or an ordinary write timeout that is too short) would still pass; assert the configured values exactly.
if cfg.ReadHeaderTimeout <= 0 || cfg.ReadTimeout <= 0 || cfg.WriteTimeout <= 0 || cfg.IdleTimeout <= 0 || cfg.MaxHeaderBytes != 8192 {
- Files reviewed: 14/14 changed files
- Comments generated: 0 new
- Review effort level: Balanced
Why
Strengthen the local terminal/browser security boundary before introducing browser approvals or prompt sending, without adding startup checks, authentication prompts, runtime services or dependency churn.
Changes
Deliberately unchanged
No browser write endpoints or approval permissions. No terminal/web launch changes, extra pairing steps, local certificates, authentication service or application-startup scanners. No Go/npm dependency version changes or frontend production asset changes. This is not complete protection against malicious local processes, browser compromise or denial of service. The Go vulnerability CI scan is Linux-native, not an exhaustive Windows/macOS-only dependency analysis.
Validation
go test -race -cover ./...passed (UI 91.2%, web 95.4%), including unchanged English presentation snapshots and new security regressions.go vet ./..., gofmt andgit diff --checkpassed.make -j4 web-testpassed: frontend check/build, embedded Go binary build and all 20 frontend tests. Production assets remain identical to main.GOTOOLCHAIN=go1.26.6 go run golang.org/x/vuln/cmd/govulncheck@v1.8.0 ./...: no vulnerabilities found.