fix(gateway): stop shared-main chat.send from inheriting stale external routes#34669
fix(gateway): stop shared-main chat.send from inheriting stale external routes#34669Sid-Qin wants to merge 1 commit intoopenclaw:mainfrom
Conversation
Greptile SummaryThis PR fixes a cross-routing bug (#34647) in the The fix: Remove the 37-line session-key-parsing and route-inheritance block entirely. Key observations:
Confidence Score: 4/5
Last reviewed commit: c2e4e0f |
|
Quick status pass on the routing cluster: this is still the canonical shared-main fix path, but I’m not merging it yet because the Bun test job is red while the other required checks are green. Once that failing job is rerun or fixed, this remains the right PR to land for the shared-main Control UI cross-routing issue tracked in #33619. |
|
The red Bun job here is not showing a repository failure. It failed while downloading Bun I’ve rerun the failed jobs so we can separate CI infrastructure noise from an actual code problem before deciding merge readiness. |
… channels
chat.send always originates from the webchat/control-UI surface. Previously,
channel-scoped session keys (e.g. agent:main:slack:direct:U…) caused
OriginatingChannel to inherit the session's stored external route, so the
reply dispatcher would route responses to Slack/Telegram instead of back to
the gateway connection. Remove the route-inheritance logic from chat.send and
always set OriginatingChannel to INTERNAL_MESSAGE_CHANNEL ("webchat").
Closes openclaw#34647
Made-with: Cursor
c2e4e0f to
15ecd73
Compare
🔒 Aisle Security AnalysisWe found 1 potential security issue(s) in this PR:
1. 🟠 Denial of Service via unbounded
|
| Property | Value |
|---|---|
| Severity | High |
| CWE | CWE-400 |
| Location | src/gateway/server-methods/chat.ts:142-145 |
Description
The resolveChatSendOriginatingRoute helper performs unbounded split(":") operations on the client-supplied sessionKey (or its parsed rest). Because sessionKey has no maxLength constraint in the gateway RPC schema, an attacker can send a very large string containing many : delimiters, causing String.prototype.split to allocate a huge array and consume excessive CPU/memory.
Impact:
- A single crafted
chat.sendrequest can trigger large allocations and high CPU usage in the gateway process. - This can lead to process slowdown or crash (DoS), especially with payloads near the WebSocket
maxPayloadlimit.
Vulnerable code:
const sessionScopeParts = (parsedSessionKey?.rest ?? params.sessionKey)
.split(":")
.filter(Boolean);Example payloads (illustrative):
sessionKey = ":".repeat(10_000_000)(creates an array with ~10M+ elements before filtering)sessionKey = "agent:main:" + ":".repeat(10_000_000)
Even though the gateway has a maxPayload limit (25MB), a 25MB string containing mostly : characters can still create an enormous split array and exhaust memory.
Recommendation
Add strict bounds and avoid unbounded split on attacker-controlled strings.
Recommended defenses (layered):
- Enforce a maximum
sessionKeylength at the protocol/schema level (and ideally also at runtime):
// Example: restrict to a reasonable size
export const ChatSendParamsSchema = Type.Object({
sessionKey: Type.String({ minLength: 1, maxLength: 256 }),
// ...
});- Parse only the small number of tokens you actually need, using the
limitargument tosplit:
const rawScope = parsedSessionKey?.rest ?? params.sessionKey;
// only need first 3 tokens (head + 2 shape candidates)
const sessionScopeParts = rawScope.split(":", 4).filter((p) => p.trim().length > 0);- Consider rejecting keys with excessive delimiter counts or total length early:
if (rawScope.length > 256) {
return { originatingChannel: INTERNAL_MESSAGE_CHANNEL, explicitDeliverRoute: false };
}These changes prevent pathological sessionKey inputs from causing large intermediate allocations.
Analyzed PR: #34669 at commit 15ecd73
Last updated on: 2026-03-06T14:24:29Z
Summary
chat.sendon shared-main and other channel-agnostic webchat sessions could inherit stale external delivery metadata from the session store and route replies out to the wrong channel.main, kept the current route-inheritance logic as the base, extracted thechat.sendroute decision into a focused helper, and narrowed the fix so channel-scoped sessions still keep explicit external delivery while shared-main/channel-agnostic webchat sessions refuse stale inherited routes.Linked Issue/PR
User-visible / Behavior Changes
2026.3.3### Fixes.Security Impact
Verification
pnpm vitest run src/gateway/server-methods/chat.directive-tags.test.tspnpm tsgopnpm checkpnpm audit --prod --audit-level highNotes
404, not a repository test failure. The rerun state was refreshed before this rebase push.