fix: prevent path traversal via session_id in session_store#3243
Conversation
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.
|
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. |
|
Thanks! To confirm — no existing session IDs use dots. The two formats in the codebase are uuid4 hex strings (e.g. |
What
load_session/save_sessioninsrc/session_store.pybuilt the session file path directly from the caller-suppliedsession_idwith no validation.Impact
A
session_idsuch as../../../../tmp/secrets— reachable from theload-sessionCLI subcommand (src/main.py:168) — let a caller read JSON files outside the.port_sessionsstore, andsave_sessioncould likewise write outside it. (Path traversal is listed as in-scope inSECURITY.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. Bothsave_sessionandload_sessionvalidate first. Legitimate ids (uuid4 hex,session-<digits>-<n>) are unaffected.Tests
Adds
SessionStorePathTraversalTeststotests/test_security_scope.py:..ids rejectedFull suite:
python3 -m unittest discover -s tests-> 50 passed.