mirror of
https://github.com/instructkr/claw-code.git
synced 2026-10-18 00:00:11 +08:00
fix(security): path containment checks for Windows environments
- Fixed an issue in extract_path_candidates where shlex.split(posix=True) would strip backslashes from Windows paths, mangling UNC paths (e.g. \\server\share) before they could be evaluated by _is_windows_absolute. - Fixed a bypass in validate_path where Windows absolute paths bypassed glob expansion and symlink resolution. On Windows, they now fall through to the standard Path logic, allowing glob expansion and strict resolution while still properly checking containment.
This commit is contained in:
1 parent
86428abce6
commit
66d73338bf
1 file changed
+7
-2
+7
-2
@@ -60,7 +60,12 @@ class WorkspacePathScope:
|
||||
def validate_path(self, candidate: str | Path, cwd: str | Path | None = None) -> PathScopeDecision:
|
||||
raw = os.path.expandvars(os.path.expanduser(str(candidate)))
|
||||
if _is_windows_absolute(raw):
|
||||
return self._validate_windows_path(raw)
|
||||
if os.name != 'nt':
|
||||
return self._validate_windows_path(raw)
|
||||
elif not any(_is_windows_absolute(str(root)) for root in self.roots):
|
||||
# Even on Windows, deny if no roots are Windows absolute paths (edge case)
|
||||
return PathScopeDecision(False, 'windows absolute path is outside workspace scope', str(candidate), raw)
|
||||
|
||||
base = Path(cwd).expanduser().resolve(strict=False) if cwd else self.roots[0]
|
||||
path = Path(raw)
|
||||
if not path.is_absolute():
|
||||
@@ -116,7 +121,7 @@ def extract_path_candidates(payload: str) -> tuple[str, ...]:
|
||||
tokens = payload.split()
|
||||
raw_tokens = payload.split()
|
||||
candidates: list[str] = []
|
||||
for token in (*tokens, *raw_tokens):
|
||||
for token in (*raw_tokens, *tokens):
|
||||
if not token or token.startswith('-') or _ENV_ASSIGNMENT_RE.match(token):
|
||||
continue
|
||||
token = _strip_redirection_operator(token)
|
||||
|
||||
Reference in new issue
Block a user