fix(sessions): multi-agent session path validation rejects valid cross-agent paths#18016
Merged
steipete merged 2 commits intoopenclaw:mainfrom Feb 16, 2026
Merged
Conversation
…tups When OPENCLAW_STATE_DIR changes between session creation and resolution (e.g., after reinstall or config change), absolute session file paths pointing to other agents' sessions directories were rejected even though they structurally match the valid .../agents/<agentId>/sessions/... pattern. The existing fallback logic in resolvePathWithinSessionsDir extracts the agent ID from the path and tries to resolve it via the current env's state directory. When those directories differ, the containment check fails. Now, if the path structurally matches the agent sessions pattern (validated by extractAgentIdFromAbsoluteSessionPath), we accept it directly as a final fallback. Fixes openclaw#15410, Fixes openclaw#15565, Fixes openclaw#15468
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.
Problem
In multi-agent setups,
resolvePathWithinSessionsDirrejects valid absolute session file paths that point to another agent's sessions directory whenOPENCLAW_STATE_DIRdiffers from the state directory used when the session was originally created.This happens because the fallback logic extracts the agent ID from the path and tries to resolve it against the current environment's state directory. When the directories don't match (e.g., after reinstall, config change, or when agents use different state dirs), the containment check fails with:
Root Cause
The hardening in v2026.2.12 (
resolvePathWithinSessionsDir) added strict containment checks. The subsequent fallback logic (resolveSiblingAgentSessionsDir+extractAgentIdFromAbsoluteSessionPath) handles cross-agent paths but only when the root state directory is consistent. When it differs, both the sibling resolution and theresolveAgentSessionsDirfallback resolve to paths under the wrong root, so containment always fails.Fix
After the existing fallbacks are exhausted, if
extractAgentIdFromAbsoluteSessionPathsuccessfully validated that the path structurally matches.../agents/<agentId>/sessions/..., accept it directly. The structural pattern already provides sufficient containment guarantees — it ensures the path is within an agent's sessions directory hierarchy.Testing
OPENCLAW_STATE_DIRdiffers from stored pathsFixes #15410, Fixes #15565, Fixes #15468
Greptile Summary
This PR fixes
resolvePathWithinSessionsDirto accept cross-agent session file paths whenOPENCLAW_STATE_DIRdiffers from the directory used when the session was created. The fix adds a final fallback (after sibling and env-based resolution attempts are exhausted) that accepts the path ifextractAgentIdFromAbsoluteSessionPathconfirms it structurally matches.../agents/<agentId>/sessions/...after full path normalization.path.normalize(path.resolve(...))to collapse all..traversal sequences before verifying theagents/<id>/sessionspattern, which prevents path escapes/etc/passwd) are still properly rejectedConfidence Score: 4/5
path.normalize(path.resolve(...))collapsing..segments before the structural pattern check. The fallback only triggers after all existing resolution strategies fail, maintaining backward compatibility. Three tests cover the positive and negative cases. The only reason this isn't a 5 is the inherent sensitivity of path containment code — filesystem-level symlinks could theoretically bypass string-based containment, but this is a pre-existing concern not introduced by this PR.src/config/sessions/paths.ts— the new fallback at line 159 inresolvePathWithinSessionsDiris security-sensitive path containment codeLast reviewed commit: 845c433