← Back to PRs

#15176: fix(sessions): allow channel-routed session IDs and cross-agent paths

by cathrynlavery open 2026-02-13 04:03 View on GitHub →
stale size: S
## Summary Session path hardening in 2026.2.12 breaks all messaging channels (iMessage, WhatsApp, Telegram, Discord) in multi-agent setups. Two regressions: 1. `SAFE_SESSION_ID_RE` rejects `:`, `+`, `@` — characters used in every channel session key (E.164 phone numbers, email handles, colon separators) 2. `resolvePathWithinSessionsDir` rejects absolute paths stored by older versions when the handler resolves a different agent's sessions directory than where the file lives (channel bindings route to agent "knox" but handler resolves "default") lobster-biscuit ## Behavior Changes - `SAFE_SESSION_ID_RE` now allows `:`, `+`, `@` and session IDs up to 255 chars (was 128). Path traversal characters (`/`, `\`, `..`) still blocked. - `resolvePathWithinSessionsDir` accepts absolute paths within the parent `agents/` directory, not just the specific agent's `sessions/` dir. Paths outside the agents root are still rejected. ## Reproduction ``` # Multi-agent setup with channel binding routing iMessage to agent "knox" # Session created under agents/knox/sessions/uuid.jsonl # Handler resolves sessionsDir for agent "default" # → relative path becomes ../../knox/sessions/uuid.jsonl → REJECTED ``` Error in gateway logs: ``` [imessage] handler failed: Error: Session file path must be within sessions directory ``` ## Tests - `pnpm build` — pass - `pnpm check` (format + types + lint) — pass - `pnpm test` — 279/279 pass New test cases added: - Session IDs with `:`, `+`, `@` pass validation - Cross-agent absolute paths within agents root accepted - Absolute paths outside agents root still rejected - All existing path traversal attack tests still pass ## Evidence Gateway error log showing every inbound iMessage rejected: ``` 2026-02-13T03:15:23.992Z [imessage] handler failed: Error: Session file path must be within sessions directory 2026-02-13T03:22:37.357Z [imessage] handler failed: Error: Session file path must be within sessions directory 2026-02-13T03:28:34.057Z [imessage] handler failed: Error: Session file path must be within sessions directory 2026-02-13T03:36:49.844Z [imessage] handler failed: Error: Session file path must be within sessions directory ``` Session store showing absolute path stored by pre-2026.2.12: ```json { "agent:knox:imessage:direct:+17189153805": { "sessionFile": "/Users/knox/.openclaw/agents/knox/sessions/2a6beef3-efaa-4b6b-bcfb-9dd76908de23.jsonl" } } ``` Fixes #15140, #15141, #15152, #15155, #15161 **Sign-Off** - Models used: Claude Opus 4.6 - Submitter effort: ~1 hour debugging + root cause analysis + fix + tests - Agent notes: Root cause identified by tracing gateway error logs → session store entries → path.relative() mismatch between bound agent (knox) and resolved agent (default). Fix verified against real session store data. <!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3> This PR relaxes session ID validation to support channel-routed keys (allowing `:`, `+`, `@` and longer IDs) and updates session transcript path resolution to accept certain absolute paths to fix multi-agent binding regressions. Main correctness concern: the new absolute-path fallback expands the trusted boundary from a specific agent’s `sessions/` directory to the entire `<state>/agents/` tree. Because the resolved path is subsequently used for filesystem reads, this can allow a corrupted/poisoned session store to redirect reads to non-session files under `agents/` (not just `agents/*/sessions/`). Tightening the allowlist to only `agents/*/sessions/**` would preserve the intended regression fix without broadening access. <h3>Confidence Score: 3/5</h3> - This PR is close to safe to merge but currently broadens session file path acceptance more than necessary. - The regression fix is well-targeted and covered by tests, but the new absolute-path fallback in `resolvePathWithinSessionsDir` permits any path under `<state>/agents/**`, which is a wider trust boundary than “cross-agent sessions” and can enable unintended file reads if session store entries are corrupted or attacker-controlled. - src/config/sessions/paths.ts <sub>Last reviewed commit: 4021ea8</sub> <!-- greptile_other_comments_section --> <sub>(4/5) You can add custom instructions or style guidelines for the agent [here](https://app.greptile.com/review/github)!</sub> <!-- /greptile_comment -->

Most Similar PRs