Skip to content

fix: prevent path traversal via session_id in session_store#3243

Open
mlzoo wants to merge 1 commit into
ultraworkers:mainfrom
mlzoo:fix/session-store-path-traversal
Open

fix: prevent path traversal via session_id in session_store#3243
mlzoo wants to merge 1 commit into
ultraworkers:mainfrom
mlzoo:fix/session-store-path-traversal

Conversation

@mlzoo

@mlzoo mlzoo commented Jun 11, 2026

Copy link
Copy Markdown

What

load_session / save_session in src/session_store.py built the session file path directly from the caller-supplied session_id with no validation.

Impact

A session_id such as ../../../../tmp/secrets — reachable from the load-session CLI subcommand (src/main.py:168) — let a caller read JSON files outside the .port_sessions store, and save_session could likewise write outside it. (Path traversal is listed as in-scope in SECURITY.md.)

Fix

Add _validate_session_id() which rejects anything outside [A-Za-z0-9_-] (path separators, .., absolute and Windows paths) before the id is used to build a filename. Both save_session and load_session validate first. Legitimate ids (uuid4 hex, session-<digits>-<n>) are unaffected.

Tests

Adds SessionStorePathTraversalTests to tests/test_security_scope.py:

  • traversal id rejected on load
  • absolute/separator/.. ids rejected
  • traversal id rejected on save
  • legitimate id round-trips (no regression)

Full suite: python3 -m unittest discover -s tests -> 50 passed.

load_session/save_session built the session file path directly from the
caller-supplied session_id with no validation, so a value like
'../../../tmp/secrets' (reachable from the 'load-session' CLI subcommand)
could read or write JSON files outside the session directory.

Add _validate_session_id() to reject anything outside [A-Za-z0-9_-]
(path separators, '..', absolute/Windows paths) before the id is used to
build a filename. Legitimate ids (uuid4 hex, 'session-<digits>-<n>') are
unaffected.

Adds SessionStorePathTraversalTests covering traversal rejection on both
load and save plus a legitimate-id round-trip.
@1716775457damn

Copy link
Copy Markdown

Nice catch on the path traversal. The whitelist approach ([A-Za-z0-9_-]) is definitely the right call over trying to sanitize dots and slashes — much simpler and less error-prone.

One minor consideration: the current allowlist excludes common session-id characters like hyphens in non-leading position. Looking at the test description it seems hyphens are already covered (_ is included), but just confirming — are there any existing session IDs in the wild that use additional safe characters like dots in a flat namespace (e.g., user.session.1)? If not, this is clean.

Security impact is clear and the test coverage looks solid. Good fix.

@mlzoo

mlzoo commented Jun 11, 2026

Copy link
Copy Markdown
Author

Thanks! To confirm — no existing session IDs use dots. The two formats in the codebase are uuid4 hex strings (e.g. a1b2c3d4e5f6...) and session-<digits>-<n>, both of which are fully covered by [A-Za-z0-9_-]. So no legitimate IDs are rejected by this allowlist.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants