Skip to content

security(gateway): route hook completion events to target agent session#73228

Merged
vincentkoc merged 1 commit into
mainfrom
clownfish/ghcrawl-156636-autonomous-smoke
Apr 28, 2026
Merged

security(gateway): route hook completion events to target agent session#73228
vincentkoc merged 1 commit into
mainfrom
clownfish/ghcrawl-156636-autonomous-smoke

Conversation

@vincentkoc

Copy link
Copy Markdown
Member

Fixes #24693.

This repairs and validates the focused implementation from #68667 by @bluesky6868. The fix routes hook completion and error system events to the hook target agent's main session instead of the default agent session, preserving cross-agent isolation for hook summaries while keeping the no-agent fallback behavior.

ProjectClownfish should rebase or refresh the contributor branch if needed, verify the Greptile loadConfig feedback remains addressed, run Codex /review, address every finding, and run pnpm check:changed before merge. Credit: original report by @abersonFAC in #24693; source PR and implementation by @bluesky6868 in #68667.

ProjectClownfish replacement details:

@aisle-research-bot

aisle-research-bot Bot commented Apr 28, 2026

Copy link
Copy Markdown

🔒 Aisle Security Analysis

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

# Severity Title
1 🟠 High Unhandled exception in hook error path can crash process (DoS) via resolveMainSessionKeyFromConfig()
1. 🟠 Unhandled exception in hook error path can crash process (DoS) via resolveMainSessionKeyFromConfig()
Property Value
Severity High
CWE CWE-248
Location src/gateway/server/hooks.ts:114-118

Description

In dispatchAgentHook, the async hook runner catches errors, but then calls resolveMainSessionKeyFromConfig() inside the catch block as a fallback when hookEventSessionKey is undefined.

  • resolveMainSessionKeyFromConfig() calls getRuntimeConfig().
  • If the original failure was due to getRuntimeConfig() throwing (e.g., invalid/missing config/env), the fallback call will throw again.
  • That second throw occurs inside the catch block and is not wrapped, which can result in an unhandled promise rejection in the void (async () => { ... })() fire-and-forget task.
  • Depending on Node.js runtime settings (unhandledRejection handling), this can crash the gateway process, creating a denial-of-service condition triggered by a hook request during config-load failure.

Vulnerable code:

} catch (err) {
  logHooks.warn(`hook agent failed: ${String(err)}`);
  enqueueSystemEvent(`Hook ${safeName} (error): ${String(err)}` , {
    sessionKey: hookEventSessionKey ?? resolveMainSessionKeyFromConfig(),
    trusted: false,
  });
}

Recommendation

Avoid calling getRuntimeConfig() (directly or indirectly) from within the error handler. Compute a safe fallback session key without re-loading config, and/or wrap the fallback in its own try/catch.

Example fix:

const fallbackSessionKey = "global"; // or a safe constant / already-known session key

let hookEventSessionKey: string | undefined;
void (async () => {
  try {
    const cfg = getRuntimeConfig();
    hookEventSessionKey = resolveHookEventSessionKey({ cfg, agentId: value.agentId });// ...
  } catch (err) {
    const sessionKeyForError = hookEventSessionKey ?? fallbackSessionKey;
    enqueueSystemEvent(`Hook ${safeName} (error): ${String(err)}`, {
      sessionKey: sessionKeyForError,
      trusted: false,
    });
  }
})();

If you need the real main session key, resolve it once in a safe place where errors can be propagated/handled (e.g., before spawning the async task), and store it in a variable.


Analyzed PR: #73228 at commit a276ca4

Last updated on: 2026-04-28T03:50:40Z

@openclaw-barnacle openclaw-barnacle Bot added gateway Gateway runtime size: S maintainer Maintainer-authored PR labels Apr 28, 2026
@greptile-apps

greptile-apps Bot commented Apr 28, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes event routing for hook completion and error system events: when a hook is dispatched with an explicit agentId, the resulting status event is now routed to that agent's main session (e.g. agent:hooks:main) rather than always defaulting to the main session. A secondary fix in the test file corrects a previously incorrect mock path (config/config.jsconfig/io.js), ensuring getRuntimeConfig was actually mocked during unit tests.

Confidence Score: 5/5

Safe to merge — the change is focused, well-tested at both the unit and integration level, and introduces no new error paths.

No P0 or P1 issues found. The implementation correctly scopes hookEventSessionKey before the awaited call so the fallback is only reachable on pre-assignment failure. The test mock fix (config/io.js) is a genuine correctness improvement. All assertions match the new routing behavior.

No files require special attention.

Reviews (1): Last reviewed commit: "security(gateway): route hook completion..." | Re-trigger Greptile

@vincentkoc
vincentkoc merged commit 6f38425 into main Apr 28, 2026
68 of 70 checks passed
@vincentkoc
vincentkoc deleted the clownfish/ghcrawl-156636-autonomous-smoke branch April 28, 2026 03:53
@vincentkoc vincentkoc added the clawsweeper Tracked by ClawSweeper automation label Apr 28, 2026
ogt-redknie pushed a commit to ogt-redknie/OPENX that referenced this pull request May 2, 2026
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 9, 2026
globalcaos pushed a commit to globalcaos/tinkerclaw that referenced this pull request May 13, 2026
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 24, 2026
jameslcowan pushed a commit to jameslcowan/openclaw that referenced this pull request Jun 2, 2026
sablehead pushed a commit to sablehead/openclaw that referenced this pull request Jun 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clawsweeper Tracked by ClawSweeper automation gateway Gateway runtime maintainer Maintainer-authored PR size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Security: Hook completion events leak cross-agent email content to default agent session

1 participant