Skip to content

Security: Path Traversal in RootedDirFileSystem._join#621

Open
tomaioo wants to merge 1 commit into
OCA:18.0from
tomaioo:fix/security/path-traversal-in-rooteddirfilesystem-jo
Open

Security: Path Traversal in RootedDirFileSystem._join#621
tomaioo wants to merge 1 commit into
OCA:18.0from
tomaioo:fix/security/path-traversal-in-rooteddirfilesystem-jo

Conversation

@tomaioo
Copy link
Copy Markdown

@tomaioo tomaioo commented May 27, 2026

Summary

Security: Path Traversal in RootedDirFileSystem._join

Problem

Severity: High | File: fs_storage/rooted_dir_file_system.py:L28

The RootedDirFileSystem._join method attempts to prevent path traversal by checking if the resolved path starts with the root path. However, the check uses os.path.normpath and make_path_posix which may not handle all path traversal techniques. Specifically, the startswith check is vulnerable if the root path is not properly normalized or if an attacker can craft a path that passes the check but still escapes the root. More critically, the startswith check with root_posix can be bypassed if the root path doesn't end with a separator and the path contains the root as a prefix. For example, if root is /data/storage, a path like /data/storage_extra would pass the startswith check but is outside the intended directory. Additionally, the method doesn't handle symlink attacks or race conditions.

Solution

Ensure the root path ends with a path separator before using startswith, or use a more robust path containment check. Consider using os.path.commonpath or ensuring both paths are resolved with os.path.realpath before comparison. Also handle the case where paths are exactly equal.

Changes

  • fs_storage/rooted_dir_file_system.py (modified)

The `RootedDirFileSystem._join` method attempts to prevent path traversal by checking if the resolved path starts with the root path. However, the check uses `os.path.normpath` and `make_path_posix` which may not handle all path traversal techniques. Specifically, the `startswith` check is vulnerable if the root path is not properly normalized or if an attacker can craft a path that passes the check but still escapes the root. More critically, the `startswith` check with `root_posix` can be bypassed if the root path doesn't end with a separator and the path contains the root as a prefix. For example, if root is `/data/storage`, a path like `/data/storage_extra` would pass the startswith check but is outside the intended directory. Additionally, the method doesn't handle symlink attacks or race conditions.

Signed-off-by: tomaioo <203048277+tomaioo@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants