Skip to content

fix(session): prevent symlink attacks in FileSessionManager#2937

Open
manus-use wants to merge 1 commit into
strands-agents:mainfrom
manus-use:fix/file-session-symlink-attack
Open

fix(session): prevent symlink attacks in FileSessionManager#2937
manus-use wants to merge 1 commit into
strands-agents:mainfrom
manus-use:fix/file-session-symlink-attack

Conversation

@manus-use

Copy link
Copy Markdown

Summary

Fixes a local privilege escalation vulnerability (GHSA-3w55-933p-8pv5) in FileSessionManager where the default use of /tmp/strands/sessions/ with predictable .tmp file paths enables symlink attacks and session data injection.

Changes

  1. Secure default storage directory — Changed from /tmp/strands/sessions/ to ~/.strands/sessions/ (user-private). Respects $XDG_DATA_HOME on Linux and %LOCALAPPDATA% on Windows.

  2. Unpredictable temp files — Replaced f"{path}.tmp" with tempfile.mkstemp() which generates cryptographically random filenames, eliminating the predictable write target.

  3. Symlink protection — Both _read_file() and _write_file() now check os.path.islink() and refuse to operate on symlinks, blocking the attack vector entirely.

  4. Restrictive permissions — All directory creation uses mode=0o700 (owner read/write/execute only).

  5. Cleanup on failure — If json.dump() or os.replace() fails, the temp file is removed in the exception handler.

Testing

  • All 39 existing test_file_session_manager.py tests pass unchanged
  • 11 new tests in test_file_session_symlink_protection.py covering:
    • Default directory is not under /tmp
    • XDG_DATA_HOME respected
    • Directory permissions are 0o700
    • Write refuses symlink targets
    • Read refuses symlink targets
    • Temp files use unpredictable names
    • Temp files cleaned up on failure
    • Full symlink attack scenario blocked
    • Atomic write correctness

Breaking Change Note

The default storage_dir changes from /tmp/strands/sessions/ to ~/.strands/sessions/. Existing sessions stored in /tmp will not be automatically migrated. Users who explicitly pass storage_dir are unaffected.

The FileSessionManager defaulted to storing session data in /tmp/strands/sessions/
(a world-writable directory) using predictable .tmp file paths that follow symlinks.
A local attacker could exploit this for:
- Arbitrary file overwrite via symlink at the .tmp path
- Persistent prompt injection via session data tampering

Changes:
- Default storage directory moved from /tmp/ to ~/.strands/sessions/
  (user-private, respects XDG_DATA_HOME on Linux)
- _write_file() now uses tempfile.mkstemp() for unpredictable temp names
- Both _read_file() and _write_file() refuse to follow symlinks
- All directory creation uses mode=0o700 (owner-only)
- Temp files are cleaned up on write failure

Fixes GHSA-3w55-933p-8pv5
@github-actions github-actions Bot added size/m area-persistence Session management or checkpointing bug Something isn't working python Pull requests that update python code labels Jun 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-persistence Session management or checkpointing bug Something isn't working python Pull requests that update python code size/m

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants