Skip to content

fix(hooks): rebind hook agent session keys to the target agent#58225

Merged
vincentkoc merged 5 commits into
mainfrom
triage-9xq6-hook-session-key
Mar 31, 2026
Merged

fix(hooks): rebind hook agent session keys to the target agent#58225
vincentkoc merged 5 commits into
mainfrom
triage-9xq6-hook-session-key

Conversation

@vincentkoc

Copy link
Copy Markdown
Member

Summary

  • Problem: hook-triggered isolated runs could keep the agent id embedded in an incoming agent: session key even when the run was explicitly routed to a different target agent.
  • Why it matters: dedicated hook agents could inherit the wrong session-scoped tool and plugin identity from that preserved prefix.
  • What changed: hook dispatch now rewrites mismatched agent: session keys to the actual target agent, keeps duplicate-target stripping intact, and adds focused unit/server tests for both cases.
  • What did NOT change: hook session-key prefix policy and request-session-key enablement rules are unchanged.

Root Cause

The hook dispatch normalizer handled duplicate target-agent prefixes, but when the incoming key was already agent-scoped for a different agent it preserved that foreign prefix instead of rebinding it to the real target agent.

Test Plan

  • Added/updated coverage in src/gateway/hooks.test.ts.
  • Added/updated coverage in src/gateway/server.hooks.test.ts.
  • Tried: pnpm test -- src/gateway/hooks.test.ts src/gateway/server.hooks.test.ts
  • Tried: direct Vitest run for the same gateway files.
  • Ran: pnpm check

Validation Notes

  • pnpm check currently fails in untouched code at src/tasks/flow-registry.ts:252 and src/tasks/flow-registry.ts:253 with string | null to string | undefined type errors.
  • The gateway Vitest lane in this worktree did not return a clean completion signal during repeated targeted reruns, even after dependency install and a direct Vitest invocation.

Human Verification

  • Verified the helper now rewrites agent:<other>:... to agent:<target>:....
  • Verified server hook dispatch forwards the rebound key into the isolated runner.

Compatibility

  • Backward compatible: Yes
  • Config/env changes: No
  • Migration needed: No

AI-assisted: yes

@vincentkoc vincentkoc self-assigned this Mar 31, 2026
@openclaw-barnacle openclaw-barnacle Bot added gateway Gateway runtime size: XS maintainer Maintainer-authored PR labels Mar 31, 2026
@greptile-apps

greptile-apps Bot commented Mar 31, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes a one-line bug in normalizeHookDispatchSessionKey (src/gateway/hooks.ts) where incoming session keys scoped to a different agent (e.g. agent:main:slack:channel:c123) were preserved as-is when dispatching to a dedicated hook agent, allowing the foreign agent identity to leak into the isolated run. The fix changes parsed.agentId to targetAgentId in the return value so the key is rebound to the actual target agent before dispatch.

Key changes:

  • src/gateway/hooks.ts: Single-line fix — replace parsed.agentId with targetAgentId so mismatched agent: prefixes are rebound rather than forwarded verbatim.
  • src/gateway/hooks.test.ts: Updates the existing unit test to assert the new (correct) rebind behavior.
  • src/gateway/server.hooks.test.ts: Adds a new integration test verifying the full dispatch path rewrites agent:main:…agent:hooks:… before the isolated runner is invoked.
  • CHANGELOG.md: Adds an entry for the fix.

Confidence Score: 5/5

Safe to merge — the fix is minimal, correct, and backed by both unit and integration tests with no regressions.

The change is a single-line fix to a clear bug where parsed.agentId was mistakenly used instead of targetAgentId. The surrounding guard conditions and the existing same-agent strip path are unchanged. Both the unit test and the new integration test confirm the correct rebind behavior end-to-end. No P0 or P1 issues were found.

No files require special attention.

Reviews (1): Last reviewed commit: "fix(hooks): rebind hook agent session ke..." | Re-trigger Greptile

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a778dfa83d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/gateway/hooks.ts Outdated
@vincentkoc
vincentkoc force-pushed the triage-9xq6-hook-session-key branch from a778dfa to 04bbf27 Compare March 31, 2026 08:59
@aisle-research-bot

aisle-research-bot Bot commented Mar 31, 2026

Copy link
Copy Markdown

🔒 Aisle Security Analysis

We found 1 potential security issue(s) in this PR:

# Severity Title
1 🔵 Low Hooks endpoint discloses allowed session key prefixes in error responses
1. 🔵 Hooks endpoint discloses allowed session key prefixes in error responses
Property Value
Severity Low
CWE CWE-209
Location src/gateway/server-http.ts:620-626

Description

The hooks HTTP handler returns an error string that includes the full configured allowlist of allowedSessionKeyPrefixes when a session key fails the prefix policy check.

  • Input: attacker-controlled sessionKey (via /hooks/agent payload or via mappings output) is normalized and checked against the configured prefixes.
  • Behavior: on failure, the API returns a 400 JSON response containing getHookSessionKeyPrefixError(allowedPrefixes), which embeds the full allowlist (e.g., internal namespace/prefix conventions).
  • Impact: anyone who can reach this code path with a valid hook token can probe and enumerate internal configuration details (session key namespace/policy), which may aid targeted attacks or reveal internal identifiers.

Vulnerable response construction:

sendJson(res, 400, { ok: false, error: getHookSessionKeyPrefixError(allowedPrefixes) });

And the error string includes the allowlist:

`sessionKey must start with one of: ${prefixes.join(", ")}`

Recommendation

Avoid echoing the full configured allowlist to external callers.

  • Return a generic error message (and optionally a stable error code) to the client.
  • Log the detailed allowlist server-side for debugging.

Example:

if (allowedPrefixes && !isSessionKeyAllowedByPrefix(normalizedDispatchSessionKey, allowedPrefixes)) {
  logHooks.warn({ allowedPrefixes }, "hook sessionKey rejected by prefix policy");
  sendJson(res, 400, { ok: false, error: "sessionKey is not allowed by policy" });
  return true;
}

If you need client guidance, consider returning only the count of allowed prefixes or a link to documentation rather than the literal prefixes.


Analyzed PR: #58225 at commit 6781e0d

Last updated on: 2026-03-31T15:18:51Z

@vincentkoc
vincentkoc merged commit 1ca12ec into main Mar 31, 2026
9 checks passed
@vincentkoc
vincentkoc deleted the triage-9xq6-hook-session-key branch March 31, 2026 15:16
steipete pushed a commit to Mlightsnow/openclaw that referenced this pull request Apr 1, 2026
…law#58225)

* fix(hooks): rebind hook agent session keys

* fix(hooks): preserve scoped hook session keys

* fix(hooks): validate normalized dispatch keys
lovewanwan pushed a commit to lovewanwan/openclaw that referenced this pull request Apr 28, 2026
…law#58225)

* fix(hooks): rebind hook agent session keys

* fix(hooks): preserve scoped hook session keys

* fix(hooks): validate normalized dispatch keys
ogt-redknie pushed a commit to ogt-redknie/OPENX that referenced this pull request May 2, 2026
…law#58225)

* fix(hooks): rebind hook agent session keys

* fix(hooks): preserve scoped hook session keys

* fix(hooks): validate normalized dispatch keys
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 9, 2026
…law#58225)

* fix(hooks): rebind hook agent session keys

* fix(hooks): preserve scoped hook session keys

* fix(hooks): validate normalized dispatch keys
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 24, 2026
…law#58225)

* fix(hooks): rebind hook agent session keys

* fix(hooks): preserve scoped hook session keys

* fix(hooks): validate normalized dispatch keys
Nachx639 pushed a commit to Nachx639/clawdbot that referenced this pull request Jun 17, 2026
…law#58225)

* fix(hooks): rebind hook agent session keys

* fix(hooks): preserve scoped hook session keys

* fix(hooks): validate normalized dispatch keys
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gateway Gateway runtime maintainer Maintainer-authored PR size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant