security(gateway): block webchat session mutators#20800
Merged
vincentkoc merged 6 commits intoopenclaw:mainfrom Feb 19, 2026
Merged
Conversation
Comment on lines
285
to
421
| "sessions.reset": async ({ params, respond }) => { | ||
| if (!assertValidParams(params, validateSessionsResetParams, "sessions.reset", respond)) { | ||
| return; | ||
| } | ||
| const p = params; | ||
| const key = requireSessionKey(p.key, respond); | ||
| if (!key) { | ||
| return; | ||
| } | ||
|
|
||
| const { cfg, target, storePath } = resolveGatewaySessionTargetFromKey(key); | ||
| const { entry } = loadSessionEntry(key); | ||
| const commandReason = p.reason === "new" ? "new" : "reset"; | ||
| const hookEvent = createInternalHookEvent( | ||
| "command", | ||
| commandReason, | ||
| target.canonicalKey ?? key, | ||
| { | ||
| sessionEntry: entry, | ||
| previousSessionEntry: entry, | ||
| commandSource: "gateway:sessions.reset", | ||
| cfg, | ||
| }, | ||
| ); | ||
| await triggerInternalHook(hookEvent); | ||
| const sessionId = entry?.sessionId; | ||
| const cleanupError = await ensureSessionRuntimeCleanup({ cfg, key, target, sessionId }); | ||
| if (cleanupError) { | ||
| respond(false, undefined, cleanupError); | ||
| return; | ||
| } | ||
| let oldSessionId: string | undefined; | ||
| let oldSessionFile: string | undefined; | ||
| const next = await updateSessionStore(storePath, (store) => { | ||
| const { primaryKey } = migrateAndPruneSessionStoreKey({ cfg, key, store }); | ||
| const entry = store[primaryKey]; | ||
| oldSessionId = entry?.sessionId; | ||
| oldSessionFile = entry?.sessionFile; | ||
| const now = Date.now(); | ||
| const nextEntry: SessionEntry = { | ||
| sessionId: randomUUID(), | ||
| updatedAt: now, | ||
| systemSent: false, | ||
| abortedLastRun: false, | ||
| thinkingLevel: entry?.thinkingLevel, | ||
| verboseLevel: entry?.verboseLevel, | ||
| reasoningLevel: entry?.reasoningLevel, | ||
| responseUsage: entry?.responseUsage, | ||
| model: entry?.model, | ||
| contextTokens: entry?.contextTokens, | ||
| sendPolicy: entry?.sendPolicy, | ||
| label: entry?.label, | ||
| origin: snapshotSessionOrigin(entry), | ||
| lastChannel: entry?.lastChannel, | ||
| lastTo: entry?.lastTo, | ||
| skillsSnapshot: entry?.skillsSnapshot, | ||
| // Reset token counts to 0 on session reset (#1523) | ||
| inputTokens: 0, | ||
| outputTokens: 0, | ||
| totalTokens: 0, | ||
| totalTokensFresh: true, | ||
| }; | ||
| store[primaryKey] = nextEntry; | ||
| return nextEntry; | ||
| }); | ||
| // Archive old transcript so it doesn't accumulate on disk (#14869). | ||
| archiveSessionTranscriptsForSession({ | ||
| sessionId: oldSessionId, | ||
| storePath, | ||
| sessionFile: oldSessionFile, | ||
| agentId: target.agentId, | ||
| reason: "reset", | ||
| }); | ||
| respond(true, { ok: true, key: target.canonicalKey, entry: next }, undefined); | ||
| }, | ||
| "sessions.delete": async ({ params, respond }) => { | ||
| "sessions.delete": async ({ params, respond, client, isWebchatConnect }) => { | ||
| if (!assertValidParams(params, validateSessionsDeleteParams, "sessions.delete", respond)) { | ||
| return; | ||
| } | ||
| const p = params; | ||
| const key = requireSessionKey(p.key, respond); | ||
| if (!key) { | ||
| return; | ||
| } | ||
| if (client?.connect && isWebchatConnect(client.connect)) { | ||
| respond( | ||
| false, | ||
| undefined, | ||
| errorShape( | ||
| ErrorCodes.INVALID_REQUEST, | ||
| "webchat clients cannot delete sessions; use chat.send for session-scoped updates", | ||
| ), | ||
| ); | ||
| return; | ||
| } | ||
|
|
||
| const { cfg, target, storePath } = resolveGatewaySessionTargetFromKey(key); | ||
| const mainKey = resolveMainSessionKey(cfg); | ||
| if (target.canonicalKey === mainKey) { | ||
| respond( | ||
| false, | ||
| undefined, | ||
| errorShape(ErrorCodes.INVALID_REQUEST, `Cannot delete the main session (${mainKey}).`), | ||
| ); | ||
| return; | ||
| } | ||
|
|
||
| const deleteTranscript = typeof p.deleteTranscript === "boolean" ? p.deleteTranscript : true; | ||
|
|
||
| const { entry } = loadSessionEntry(key); | ||
| const sessionId = entry?.sessionId; | ||
| const existed = Boolean(entry); | ||
| const cleanupError = await ensureSessionRuntimeCleanup({ cfg, key, target, sessionId }); | ||
| if (cleanupError) { | ||
| respond(false, undefined, cleanupError); | ||
| return; | ||
| } | ||
| await updateSessionStore(storePath, (store) => { | ||
| const { primaryKey } = migrateAndPruneSessionStoreKey({ cfg, key, store }); | ||
| if (store[primaryKey]) { | ||
| delete store[primaryKey]; | ||
| } | ||
| }); | ||
|
|
||
| const archived = deleteTranscript | ||
| ? archiveSessionTranscriptsForSession({ | ||
| sessionId, | ||
| storePath, | ||
| sessionFile: entry?.sessionFile, | ||
| agentId: target.agentId, | ||
| reason: "deleted", | ||
| }) | ||
| : []; | ||
|
|
||
| respond(true, { ok: true, key: target.canonicalKey, deleted: existed, archived }, undefined); | ||
| }, | ||
| "sessions.compact": async ({ params, respond }) => { |
Contributor
There was a problem hiding this comment.
Check that sessions.reset (line 285) and sessions.compact (line 421) intentionally allow WebChat clients - both methods mutate session state similar to patch/delete
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/gateway/server-methods/sessions.ts
Line: 285-421
Comment:
Check that `sessions.reset` (line 285) and `sessions.compact` (line 421) intentionally allow WebChat clients - both methods mutate session state similar to patch/delete
How can I resolve this? If you propose a fix, please make it concise.
Closed
6 tasks
mmyyfirstb
pushed a commit
to mmyyfirstb/openclaw
that referenced
this pull request
Feb 21, 2026
* chore(ci): local claude settings gitignore * Gateway: block webchat session mutators * Changelog: note webchat session mutator guard * Changelog: credit report for webchat mutator guard
18 tasks
xianfeng92
pushed a commit
to xianfeng92/openclaw
that referenced
this pull request
Feb 24, 2026
* chore(ci): local claude settings gitignore * Gateway: block webchat session mutators * Changelog: note webchat session mutator guard * Changelog: credit report for webchat mutator guard (cherry picked from commit 981d266)
18 tasks
6 tasks
hughdidit
pushed a commit
to hughdidit/DAISy-Agency
that referenced
this pull request
Mar 1, 2026
* chore(ci): local claude settings gitignore * Gateway: block webchat session mutators * Changelog: note webchat session mutator guard * Changelog: credit report for webchat mutator guard (cherry picked from commit 981d266) # Conflicts: # .gitignore # CHANGELOG.md # src/gateway/server-methods/sessions.ts # src/gateway/server.sessions.gateway-server-sessions-a.e2e.test.ts
6 tasks
hughdidit
pushed a commit
to hughdidit/DAISy-Agency
that referenced
this pull request
Mar 3, 2026
* chore(ci): local claude settings gitignore * Gateway: block webchat session mutators * Changelog: note webchat session mutator guard * Changelog: credit report for webchat mutator guard (cherry picked from commit 981d266) # Conflicts: # .gitignore # CHANGELOG.md # src/gateway/server-methods/sessions.ts # src/gateway/server.sessions.gateway-server-sessions-a.e2e.test.ts
zooqueen
pushed a commit
to hanzoai/bot
that referenced
this pull request
Mar 6, 2026
* chore(ci): local claude settings gitignore * Gateway: block webchat session mutators * Changelog: note webchat session mutator guard * Changelog: credit report for webchat mutator guard
19 tasks
vincentkoc
added a commit
that referenced
this pull request
Mar 30, 2026
…oks.md - Add reference table for all 27 plugin hook names with execution model and return types - Fix agent:bootstrap context: add missing sessionKey, sessionId, agentId fields - Fix session patch context: add fastMode, spawnedWorkspaceDir, subagentRole, subagentControlScope - Fix responseUsage: add backwards-compat "on" value - Add session:compact:before and session:compact:after payload field documentation - Remove internal PR reference (#20800) - Fix handler file resolution: document handler.js and index.js fallbacks
Alix-007
pushed a commit
to Alix-007/openclaw
that referenced
this pull request
Mar 30, 2026
…oks.md - Add reference table for all 27 plugin hook names with execution model and return types - Fix agent:bootstrap context: add missing sessionKey, sessionId, agentId fields - Fix session patch context: add fastMode, spawnedWorkspaceDir, subagentRole, subagentControlScope - Fix responseUsage: add backwards-compat "on" value - Add session:compact:before and session:compact:after payload field documentation - Remove internal PR reference (openclaw#20800) - Fix handler file resolution: document handler.js and index.js fallbacks
alexjiang1
pushed a commit
to alexjiang1/openclaw
that referenced
this pull request
Mar 31, 2026
…oks.md - Add reference table for all 27 plugin hook names with execution model and return types - Fix agent:bootstrap context: add missing sessionKey, sessionId, agentId fields - Fix session patch context: add fastMode, spawnedWorkspaceDir, subagentRole, subagentControlScope - Fix responseUsage: add backwards-compat "on" value - Add session:compact:before and session:compact:after payload field documentation - Remove internal PR reference (openclaw#20800) - Fix handler file resolution: document handler.js and index.js fallbacks
pgondhi987
pushed a commit
to pgondhi987/openclaw
that referenced
this pull request
Mar 31, 2026
…oks.md - Add reference table for all 27 plugin hook names with execution model and return types - Fix agent:bootstrap context: add missing sessionKey, sessionId, agentId fields - Fix session patch context: add fastMode, spawnedWorkspaceDir, subagentRole, subagentControlScope - Fix responseUsage: add backwards-compat "on" value - Add session:compact:before and session:compact:after payload field documentation - Remove internal PR reference (openclaw#20800) - Fix handler file resolution: document handler.js and index.js fallbacks
lovewanwan
pushed a commit
to lovewanwan/openclaw
that referenced
this pull request
Apr 28, 2026
* chore(ci): local claude settings gitignore * Gateway: block webchat session mutators * Changelog: note webchat session mutator guard * Changelog: credit report for webchat mutator guard
lovewanwan
pushed a commit
to lovewanwan/openclaw
that referenced
this pull request
Apr 28, 2026
…oks.md - Add reference table for all 27 plugin hook names with execution model and return types - Fix agent:bootstrap context: add missing sessionKey, sessionId, agentId fields - Fix session patch context: add fastMode, spawnedWorkspaceDir, subagentRole, subagentControlScope - Fix responseUsage: add backwards-compat "on" value - Add session:compact:before and session:compact:after payload field documentation - Remove internal PR reference (openclaw#20800) - Fix handler file resolution: document handler.js and index.js fallbacks
Tardisyuan
pushed a commit
to Tardisyuan/openclaw
that referenced
this pull request
Apr 30, 2026
…oks.md - Add reference table for all 27 plugin hook names with execution model and return types - Fix agent:bootstrap context: add missing sessionKey, sessionId, agentId fields - Fix session patch context: add fastMode, spawnedWorkspaceDir, subagentRole, subagentControlScope - Fix responseUsage: add backwards-compat "on" value - Add session:compact:before and session:compact:after payload field documentation - Remove internal PR reference (openclaw#20800) - Fix handler file resolution: document handler.js and index.js fallbacks
ogt-redknie
pushed a commit
to ogt-redknie/OPENX
that referenced
this pull request
May 2, 2026
* chore(ci): local claude settings gitignore * Gateway: block webchat session mutators * Changelog: note webchat session mutator guard * Changelog: credit report for webchat mutator guard
ogt-redknie
pushed a commit
to ogt-redknie/OPENX
that referenced
this pull request
May 2, 2026
…oks.md - Add reference table for all 27 plugin hook names with execution model and return types - Fix agent:bootstrap context: add missing sessionKey, sessionId, agentId fields - Fix session patch context: add fastMode, spawnedWorkspaceDir, subagentRole, subagentControlScope - Fix responseUsage: add backwards-compat "on" value - Add session:compact:before and session:compact:after payload field documentation - Remove internal PR reference (openclaw#20800) - Fix handler file resolution: document handler.js and index.js fallbacks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
sessions.patch,sessions.delete).sessions.patchandsessions.deleteto reject these calls with clear errors.Change Type (select all)
Scope (select all touched areas)
Linked Issue/PR
User-visible / Behavior Changes
INVALID_REQUESTerror when attemptingsessions.patchorsessions.delete.Security Impact (required)
Yes/No): NoYes/No): NoYes/No): NoYes/No): NoYes/No): YesYes, explain risk + mitigation:Repro + Verification
Environment
Steps
sessions.patchfor another session key.sessions.deletefor another session key.Expected
Actual
INVALID_REQUESTmessages.Evidence
Attach at least one:
Human Verification (required)
What you personally verified (not just CI), and how:
Compatibility / Migration
Yes/No): YesYes/No): NoYes/No): NoFailure Recovery (if this breaks)
6c1830bf7.src/gateway/server-methods/sessions.ts,src/gateway/server.sessions.gateway-server-sessions-a.e2e.test.tsINVALID_REQUESTfor non-WebChat clients (should not occur).Risks and Mitigations
isWebchatConnect(client.connect).Agent-Signoff: Shellfish-Guard
Greptile Summary
Added WebChat client guards to
sessions.patchandsessions.deleteto prevent session-store mutations outside of chat flows. The guards properly check client type usingisWebchatConnect()and return clearINVALID_REQUESTerrors. Implementation is clean, well-tested, and maintains backward compatibility for non-WebChat clients.Confidence Score: 4/5
Last reviewed commit: d127e01