From aa2aac68b004fbef7ba7ea9c2abd4e1bcea670f8 Mon Sep 17 00:00:00 2001 From: OrbisAI Security Date: Fri, 5 Jun 2026 13:40:50 +0530 Subject: [PATCH] fix(V-009): reject Windows drive-letter paths in session field validation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extends the CWE-22 path traversal guard to cover Windows absolute paths of the form C:/... and D:\... — previously only leading / and \ were checked, which missed drive-letter prefixes. Replaces the inline startswith check with a compiled module-level regex (_TRAVERSAL_RE) that covers all three attack patterns: .., leading /\, and leading X: drives. Adds two regression tests for C:/windows/system32 and D:\\path\\to\\file. Co-Authored-By: Claude Sonnet 4.6 --- gateway/session.py | 8 +++++++- tests/gateway/test_session.py | 10 ++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/gateway/session.py b/gateway/session.py index e7f4f47d35e..941722e4d96 100644 --- a/gateway/session.py +++ b/gateway/session.py @@ -12,6 +12,7 @@ import hashlib import logging import os import json +import re import threading import uuid from pathlib import Path @@ -66,6 +67,11 @@ from .whatsapp_identity import ( ) from utils import atomic_replace +# Matches any value that could escape the sessions directory as a file path. +# Covers: directory traversal (..), Unix/Windows absolute paths (/ \), +# and Windows drive-letter paths (C:/ D:\\ etc.). +_TRAVERSAL_RE = re.compile(r'\.\.|^[/\\]|^[A-Za-z]:') + @dataclass class SessionSource: @@ -578,7 +584,7 @@ class SessionEntry: # Validate path-sensitive fields to prevent directory traversal (CWE-22) for _field, _val in (("session_key", session_key), ("session_id", session_id)): - if _val and (".." in str(_val) or str(_val).startswith(("/", "\\"))): + if _val and _TRAVERSAL_RE.search(str(_val)): raise ValueError( f"Invalid {_field}: potential directory traversal detected" ) diff --git a/tests/gateway/test_session.py b/tests/gateway/test_session.py index d42a3be4e70..55611b8c0c5 100644 --- a/tests/gateway/test_session.py +++ b/tests/gateway/test_session.py @@ -1085,6 +1085,16 @@ class TestSessionEntryFromDictTraversalValidation: with pytest.raises(ValueError, match="session_id"): SessionEntry.from_dict(self._entry(session_id="\\windows\\system32\\config")) + def test_session_id_windows_drive_letter_raises(self): + from gateway.session import SessionEntry + with pytest.raises(ValueError, match="session_id"): + SessionEntry.from_dict(self._entry(session_id="C:/windows/system32")) + + def test_session_id_windows_drive_backslash_raises(self): + from gateway.session import SessionEntry + with pytest.raises(ValueError, match="session_id"): + SessionEntry.from_dict(self._entry(session_id="D:\\path\\to\\file")) + class TestEnsureLoadedSkipsInvalidEntries: """Regression: one bad sessions.json entry must not block valid entries from loading."""