Skip to content

Commit ed7901d

Browse files
πŸ›‘οΈ Sentinel: [CRITICAL] Fix OAuth callback server binding
🚨 Severity: CRITICAL πŸ’‘ Vulnerability: Ephemeral local HTTP servers used for OAuth callbacks (`packages/opencode/src/mcp/oauth-callback.ts` and `packages/opencode/src/plugin/codex.ts`) were omitting the `hostname` parameter in `Bun.serve`. This caused the server to bind to `0.0.0.0` (all interfaces) by default instead of `127.0.0.1` (localhost). 🎯 Impact: This breaks the local-first security boundary, exposing local OAuth flows to the entire local network and potentially allowing attackers to intercept callbacks or perform CSRF attacks. πŸ”§ Fix: Explicitly set `hostname: "127.0.0.1"` in `Bun.serve` configurations. βœ… Verification: `bun turbo typecheck`, `bun run format`, and backend tests (`bun test`) passed. A journal entry was also recorded. Co-authored-by: PrakharMNNIT <73683289+PrakharMNNIT@users.noreply.github.com>
1 parent e996537 commit ed7901d

28 files changed

Lines changed: 1198 additions & 751 deletions

β€Ž.jules/sentinel.mdβ€Ž

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
## 2025-02-25 - Bun.serve default bindings
2+
3+
**Vulnerability:** Ephemeral local HTTP servers used for OAuth callbacks (`packages/opencode/src/mcp/oauth-callback.ts` and `packages/opencode/src/plugin/codex.ts`) were omitting the `hostname` parameter in `Bun.serve`. This causes the server to bind to `0.0.0.0` (all interfaces) by default instead of `127.0.0.1` (localhost).
4+
5+
**Learning:** In a local-first application, assuming `Bun.serve` binds to localhost by default is a critical mistake. It binds to all network interfaces, exposing local OAuth flows, webhooks, or inter-process communication servers to the entire local network, which breaks the local-only security boundary.
6+
7+
**Prevention:** Every time `Bun.serve` is used to spawn a local server, `hostname: "127.0.0.1"` MUST be explicitly passed to prevent exposing the service to the network, unless mDNS or explicit external networking is intentionally enabled and authenticated.

β€ŽAI_REVIEW.mdβ€Ž

Lines changed: 119 additions & 145 deletions
Large diffs are not rendered by default.

β€Žbun.lockβ€Ž

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

β€Ždocs/09-temp/cline-subagent-research.mdβ€Ž

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,13 @@
1717
- **CLI Subagent Command Transformation**: `src/integrations/cli-subagents/subagent_command.ts`
1818
- `isSubagentCommand()` β€” identifies simplified cline commands
1919
- `transformClineCommand()` β€” injects `--json -y` flags for autonomous execution
20-
2120
- **Agent Client Protocol (ACP)**: `cli/src/acp/AcpAgent.ts`
2221
- Bridges ClineAgent with AgentSideConnection for stdio-based communication
2322
- Handles permission requests, forwards session events
24-
2523
- **ClineAgent**: `cli/src/agent/ClineAgent.ts`
2624
- Implements ACP agent interface
2725
- Translates ACP requests into core Controller operations
2826
- Manages authentication, session modes, processes user prompts
29-
3027
- **Message Translator**: `cli/src/agent/messageTranslator.ts`
3128
- Converts ClineMessage objects to ACP SessionUpdate messages
3229
- Computes deltas for streaming (avoids duplicate content)
@@ -40,19 +37,22 @@
4037
## Comparison with OpenCode's Subagent System
4138

4239
OpenCode already has subagents (`TaskTool` in `packages/opencode/src/tool/task.ts`):
40+
4341
- Subagents are spawned via the `task` tool
4442
- Each subagent gets its own child session
4543
- Subagent types: explore, plan, general (configurable per agent)
4644
- Results returned as tool output to parent session
4745

4846
**Gaps to investigate:**
47+
4948
- Does Cline support parallel subagents? (OpenCode does via plan mode Phase 1)
5049
- How does Cline's ACP protocol compare to opencode's Bus event system?
5150
- Can we adopt Cline's streaming delta pattern for subagent updates?
5251

5352
## Tonight's Session Summary (2026-02-24, 2:37 AM - 4:57 AM)
5453

5554
### 6 PRs Submitted to opencode (sst/opencode):
55+
5656
1. **#14820** β€” Streaming content duplication fix (global-sdk.tsx voided Set)
5757
2. **#14821** β€” Font size settings (CSS vars + terminal + UI stepper)
5858
3. **#14826** β€” ContextOverflowError auto-recovery (processor.ts)
@@ -61,6 +61,7 @@ OpenCode already has subagents (`TaskTool` in `packages/opencode/src/tool/task.t
6161
6. **#14835** β€” Wide mode setting (full-width chat toggle)
6262

6363
### Issues Created:
64+
6465
- #14822, #14823, #14824, #14825, #14830, #14834
6566

6667
### All branches merged into `origin/dev` on fork (PrakharMNNIT/opencode)

β€Ždocs/09-temp/codex-queue-steer-architecture.mdβ€Ž

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99

1010
Codex implements a **dual-input model** that lets users interact with the agent **during** an active turn, not just between turns:
1111

12-
| Action | Keybinding | Behavior | When Turn Active |
13-
|--------|-----------|----------|-----------------|
14-
| **Queue** | `Enter` | Enqueue message for next turn boundary | Message waits in queue, displayed in UI |
12+
| Action | Keybinding | Behavior | When Turn Active |
13+
| --------- | ------------------------------- | ----------------------------------------- | ---------------------------------------- |
14+
| **Queue** | `Enter` | Enqueue message for next turn boundary | Message waits in queue, displayed in UI |
1515
| **Steer** | `⌘Enter` / `Enter` (steer-mode) | Inject input into active turn immediately | Message sent to model in current context |
1616

1717
---
@@ -201,14 +201,14 @@ When `NoActiveTurn` occurs, the app-server falls back β€” the input that failed
201201

202202
### Critical Difference
203203

204-
| Aspect | Queue | Steer |
205-
|--------|-------|-------|
206-
| **Timing** | After turn ends | During active turn |
207-
| **Turn boundary** | Creates new turn | Same turn continues |
208-
| **Model sees it** | On next turn start | At next loop iteration |
209-
| **Cancels response** | No (waits) | No (appends to context) |
210-
| **UI display** | Queued messages widget | Injected into chat transcript |
211-
| **Fallback** | N/A | Falls back to queue if no active turn |
204+
| Aspect | Queue | Steer |
205+
| -------------------- | ---------------------- | ------------------------------------- |
206+
| **Timing** | After turn ends | During active turn |
207+
| **Turn boundary** | Creates new turn | Same turn continues |
208+
| **Model sees it** | On next turn start | At next loop iteration |
209+
| **Cancels response** | No (waits) | No (appends to context) |
210+
| **UI display** | Queued messages widget | Injected into chat transcript |
211+
| **Fallback** | N/A | Falls back to queue if no active turn |
212212

213213
---
214214

@@ -285,11 +285,13 @@ Steer is gated behind `Feature::Steer` in the TUI:
285285
## Implications for OpenCode
286286

287287
### What OpenCode Currently Has
288+
288289
- Session/turn model with `processor.ts` handling model interaction
289290
- Parallel agents via `task.ts` tool
290291
- No mid-turn input injection
291292

292293
### What Queue/Steer Would Add
294+
293295
1. **Pending input buffer** on the session/turn state
294296
2. **Steer RPC** that pushes to the buffer while model is running
295297
3. **Loop-boundary drain** that checks for pending input after each model response
@@ -298,6 +300,7 @@ Steer is gated behind `Feature::Steer` in the TUI:
298300
6. **Fallback path**: steer β†’ queue if no active turn
299301

300302
### Key Implementation Points
303+
301304
- `steer_input()` is a **lock-based, non-cancelling** approach β€” it doesn't abort the model stream
302305
- Pending input is consumed at the **top of the agentic loop**, not mid-stream
303306
- The model sees steered input as additional conversation items on its next iteration

β€Ždocs/09-temp/escape-key-ux-research.mdβ€Ž

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,32 @@
44
**Status:** TODO β€” brainstorm in next session
55

66
## Problem
7+
78
Pressing Escape accidentally during AI response immediately stops the response with no confirmation. No visual feedback in chat that response was interrupted.
89

910
## Current Behavior
11+
1012
- Escape β†’ immediately cancels the LLM response
1113
- Shows a notification/warning toast
1214
- No visual indicator in the chat thread that the message was interrupted
1315
- No confirmation dialog before cancelling
1416

1517
## User's Proposed Improvements
18+
1619
1. **Confirmation before cancel** β€” Alert/dialog: "Are you sure you want to interrupt?"
1720
2. **Visual interruption indicator** β€” Show in chat that the message was interrupted (red line, badge, etc.)
1821
3. **Better UX** β€” Maybe double-tap Escape to cancel, or Escape once to show warning
1922

2023
## Files to Investigate
24+
2125
- `packages/app/src/pages/session.tsx` β€” handleKeyDown, Escape handling
2226
- `packages/app/src/components/prompt-input.tsx` β€” Escape key handling in input
2327
- `packages/opencode/src/session/prompt.ts` β€” cancel() function
2428
- `packages/ui/src/components/message-part.tsx` β€” interrupted state rendering
2529
- `packages/app/src/pages/session/use-session-commands.tsx` β€” session.cancel command
2630

2731
## Design Questions
32+
2833
1. Should Escape require double-tap? (like VS Code terminal)
2934
2. Should there be a small "Esc to cancel" indicator during streaming?
3035
3. Should interrupted messages have a visual indicator (red border/badge)?

0 commit comments

Comments
Β (0)