From ef09a63893913a435d649d03d58a3564d836b43c Mon Sep 17 00:00:00 2001 From: Amir Fathi Date: Sat, 5 Sep 2026 10:42:07 +0000 Subject: [PATCH] fix(sandbox-lint): normalise every trailing slash, not just one _normalise() stripped a single trailing slash so a config path and its slash variant compare equal against FORBIDDEN_ALLOW_READ / FORBIDDEN_ALLOW_WRITE. A path with two or more trailing slashes (e.g. "~/.ssh//") only lost one, so it never matched the forbidden entry and check_invariants() reported no violation for a config that grants read or write access into a credential directory. Strip all trailing slashes instead, keeping the bare-root case ("/") intact. Added a double-slash case to the existing parametrized allowRead/allowWrite tests; both fail on main and pass with this change. Generated-by: Claude Code (Sonnet 5) --- tools/sandbox-lint/src/sandbox_lint/__init__.py | 12 +++++------- tools/sandbox-lint/tests/test_validator.py | 2 ++ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tools/sandbox-lint/src/sandbox_lint/__init__.py b/tools/sandbox-lint/src/sandbox_lint/__init__.py index e9cf173bc..a617166c7 100644 --- a/tools/sandbox-lint/src/sandbox_lint/__init__.py +++ b/tools/sandbox-lint/src/sandbox_lint/__init__.py @@ -121,15 +121,13 @@ def _normalise(path: str) -> str: - """Strip a single trailing slash so '~/.aws' and '~/.aws/' compare equal. + """Strip all trailing slashes so '~/.aws' and '~/.aws//' compare equal. - The sandbox treats both forms as the same directory; the validator - must too, otherwise the forbidden-list could be bypassed by a - trailing-slash variant. + The sandbox treats every trailing-slash count as the same directory; + the validator must too, otherwise the forbidden-list could be bypassed + by a multi-slash variant. """ - if path.endswith("/") and len(path) > 1: - return path[:-1] - return path + return path.rstrip("/") or "/" def _normalised_set(paths: list[str]) -> set[str]: diff --git a/tools/sandbox-lint/tests/test_validator.py b/tools/sandbox-lint/tests/test_validator.py index 791664835..497d95bdb 100644 --- a/tools/sandbox-lint/tests/test_validator.py +++ b/tools/sandbox-lint/tests/test_validator.py @@ -163,6 +163,7 @@ def test_invariant_missing_deny_read_root(baseline: dict[str, Any]) -> None: "~/.config/gcloud", "/", "~/", + "~/.ssh//", ], ) def test_invariant_allow_read_rejects_credential_paths(baseline: dict[str, Any], forbidden: str) -> None: @@ -181,6 +182,7 @@ def test_invariant_allow_read_rejects_credential_paths(baseline: dict[str, Any], "~/.gnupg", "~/.ssh", "~/.aws/", + "~/.aws//", ], ) def test_invariant_allow_write_rejects_credential_paths(baseline: dict[str, Any], forbidden: str) -> None: