Skip to content

fix(session): prevent path traversal in JSONSession (CWE-22)#1250

Closed
shlokmestry wants to merge 1 commit intoagentscope-ai:mainfrom
shlokmestry:fix/jsonsession-path-traversal
Closed

fix(session): prevent path traversal in JSONSession (CWE-22)#1250
shlokmestry wants to merge 1 commit intoagentscope-ai:mainfrom
shlokmestry:fix/jsonsession-path-traversal

Conversation

@shlokmestry
Copy link
Copy Markdown
Contributor

AgentScope Version

1.0.16

Description

This PR fixes a path traversal vulnerability in JSONSession
(CWE-22: Improper Limitation of a Pathname to a Restricted Directory).

Background

session_id and user_id were used to construct file paths for
session persistence. While os.path.basename() was applied,
malicious traversal inputs (e.g. "../evil") were silently
sanitized instead of being explicitly rejected.

This could allow unintended file path manipulation under certain
conditions.

Changes

  • Reject absolute paths
  • Reject ".." traversal patterns
  • Reject path separators in identifiers
  • Add realpath containment validation to ensure generated paths
    cannot escape save_dir
  • Add regression test:
    test_jsonsession_rejects_path_traversal

Security Impact

Prevents directory traversal attacks when saving or loading
session state files.

Tests

  • pytest tests/session_test.py -q
  • All session tests pass under Python 3.11
  • Regression test confirms traversal attempts raise ValueError

Checklist

  • Code has been formatted
  • All relevant tests are passing
  • Regression test added
  • Code is ready for review

@cla-assistant
Copy link
Copy Markdown

cla-assistant bot commented Feb 19, 2026

CLA assistant check
All committers have signed the CLA.

@cla-assistant
Copy link
Copy Markdown

cla-assistant bot commented Feb 19, 2026

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @shlokmestry, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses a critical path traversal vulnerability (CWE-22) within the JSONSession component. The changes enhance security by rigorously validating session_id and user_id inputs, preventing malicious manipulation of file paths during session persistence. This ensures that session files are always saved and loaded within their intended directory, significantly improving the robustness of the session management system against directory traversal attacks.

Highlights

  • Path Traversal Prevention: Implemented strict validation in JSONSession to prevent path traversal vulnerabilities (CWE-22) by rejecting absolute paths, .. patterns, and path separators in session_id and user_id.
  • Realpath Containment: Added a defense-in-depth check using os.path.realpath to ensure generated file paths remain strictly within the designated save_dir.
  • New Validation Method: Introduced a private _validate_identifier method to centralize the logic for validating session and user identifiers.
  • Regression Test: Included a new test case test_jsonsession_rejects_path_traversal to confirm that traversal attempts correctly raise ValueError.
Changelog
  • src/agentscope/session/_json_session.py
    • Initialized self.save_dir with os.path.abspath to ensure an absolute path.
    • Added a new private method _validate_identifier to check for absolute paths, .. patterns, and path separators in input values.
    • Modified _get_save_path to utilize _validate_identifier for both session_id and user_id.
    • Implemented a os.path.realpath check within _get_save_path to verify that the final path is contained within save_dir.
    • Updated calls to _get_save_path in save_session_state and load_session_state to use the new secure logic.
    • Refined docstrings for save_session_state and load_session_state for clarity.
  • tests/session_test.py
    • Imported the tempfile module for creating temporary directories in tests.
    • Added a new asynchronous test test_jsonsession_rejects_path_traversal to validate the path traversal prevention mechanisms.
    • Removed extraneous comments from asyncTearDown in JSONSessionTest and asyncSetUp in RedisSessionTest.
    • Removed a comment from test_redis_session_save_and_load.
Activity
  • No human activity has been recorded on this pull request yet.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a critical security fix to prevent path traversal vulnerabilities in JSONSession. The changes are robust, implementing multiple layers of validation for session_id and user_id, including checks for absolute paths, traversal patterns, and a final realpath containment check. A regression test has been added to confirm the fix. My review focuses on improving the documentation by ensuring all new and modified methods have complete docstrings that adhere to the repository's style guide, which is a [MUST] requirement. The provided rules did not apply to any of the comments, so all original comments have been kept.

def _get_save_path(self, session_id: str, user_id: str) -> str:
"""The path to save the session state.
def _validate_identifier(self, value: str) -> None:
"""Validate session_id and user_id against path traversal."""
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.

medium

The docstring for this new method is incomplete. According to the repository's style guide (line 46), all methods must have a complete docstring including descriptions of arguments and what they raise.

        """Validate session_id and user_id against path traversal.

        Args:
            value (`str`):
                The identifier to validate.

        Raises:
            ValueError: If the identifier is invalid, e.g., contains
                absolute paths, traversal patterns, or path separators.
        """
References
  1. All classes/methods must have complete docstrings, strictly following the provided template which includes Args, Returns, and other sections. (link)

raise ValueError("Invalid session_id/user_id")

def _get_save_path(self, session_id: str, user_id: str) -> str:
"""The path to save the session state."""
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.

medium

The docstring for _get_save_path is incomplete. The repository style guide (line 46) requires a full docstring with Args, Returns, and Raises sections.

        """Get the secure path to save the session state.

        This function validates session_id and user_id to prevent path
        traversal attacks and returns a secure, absolute path for the
        session file.

        Args:
            session_id (`str`):
                The session id.
            user_id (`str`):
                The user ID for the storage.

        Returns:
            `str`:
                The absolute path to save the session state.

        Raises:
            ValueError: If path traversal is detected in session_id or user_id.
        """
References
  1. All classes/methods must have complete docstrings, strictly following the provided template which includes Args, Returns, and other sections. (link)

**state_modules_mapping (`dict[str, StateModule]`):
A dictionary mapping of state module names to their instances.
"""
"""Save the state dictionary to a JSON file."""
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.

medium

The docstring for save_session_state is incomplete. While the description has been corrected, it's missing the Args section required by the repository's style guide (line 46). Please provide a complete docstring.

        """Save the state dictionary to a JSON file.

        Args:
            session_id (`str`):
                The session id.
            user_id (`str`, default to `""`):
                The user ID for the storage.
            **state_modules_mapping (`dict[str, StateModule]`):
                A dictionary mapping of state module names to their instances.
        """
References
  1. All classes/methods must have complete docstrings, strictly following the provided template which includes Args, Returns, and other sections. (link)

state_modules_mapping (`list[StateModule]`):
The list of state modules to be loaded.
"""
"""Load the state dictionary from a JSON file."""
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.

medium

The docstring for load_session_state is incomplete. It should include the Args section as required by the repository's style guide (line 46).

        """Load the state dictionary from a JSON file.

        Args:
            session_id (`str`):
                The session id.
            user_id (`str`, default to `""`):
                The user ID for the storage.
            allow_not_exist (`bool`, defaults to `True`):
                Whether to allow the session to not exist. If `False`, raises
                an error if the session does not exist.
            **state_modules_mapping (`dict[str, StateModule]`):
                The mapping of state modules to be loaded.
        """
References
  1. All classes/methods must have complete docstrings, strictly following the provided template which includes Args, Returns, and other sections. (link)

@DavdGao DavdGao added the state: under review The pull request is under review label Mar 11, 2026
@shlokmestry shlokmestry closed this Apr 1, 2026
@shlokmestry shlokmestry deleted the fix/jsonsession-path-traversal branch April 1, 2026 10:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

state: under review The pull request is under review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants