Skip to content

Commit 1f8b351

Browse files
committed
fix(capability): detect native Windows private paths in public-safe-outbound
The builtin fail-closed pre-submission scrub only recognized the POSIX spelling of a private absolute path. On a Windows host the same private path written as C:\Users\<name>\... or \\server\Users\<name>\... passed the scan with hit_count 0 while its POSIX spelling was blocked, so the guard was silent on the platform whose users spell their private paths that way. #6161 repaired the same spelling class in the public/private boundary scan and named this rule as its deliberately deferred successor owner. Extend private_abs_path with drive-letter and UNC arms carrying the same root keywords, and cover both native spellings plus a non-private drive path in the scanner tests. Closes #6220 Follow-up to #6161 Signed-off-by: JasonBuildAI <jasonbuildai@gmail.com>
1 parent 3d7b72a commit 1f8b351

2 files changed

Lines changed: 38 additions & 2 deletions

File tree

‎loopx/capabilities/public_safe_outbound/scanner.py‎

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,18 @@
2727
{"id": "aklt_access_key", "label": "AK/SK access key", "pattern": r"\b" + "AKLT" + r"[A-Za-z0-9]{10,}\b"},
2828
{"id": "private_key_block", "label": "private key block", "pattern": r"-----BEGIN (RSA |EC |OPENSSH )?PRIVATE KEY-----"},
2929
{"id": "api_key_assignment", "label": "api key assignment", "pattern": r"(?i)\b(api[_-]?key|access[_-]?key|secret)\b\s*[=:]\s*['\"][^'\"]{8,}['\"]"},
30-
# private absolute paths
31-
{"id": "private_abs_path", "label": "private absolute path", "pattern": r"/(Users|home|data00|root)/([A-Za-z0-9_.-]+)/"},
30+
# Private absolute paths: the POSIX spellings, plus the native Windows
31+
# drive-letter and UNC spellings of the same roots, so a Windows host's own
32+
# path form is a hit instead of a silent pass.
33+
{
34+
"id": "private_abs_path",
35+
"label": "private absolute path",
36+
"pattern": (
37+
r"/(?:Users|home|data00|root)/[A-Za-z0-9_.-]+/"
38+
r"|[A-Za-z]:[\\/](?:Users|home|data00|root)[\\/][A-Za-z0-9_.-]+[\\/]"
39+
r"|\\\\[A-Za-z0-9_.-]+\\(?:Users|home|data00|root)\\[A-Za-z0-9_.-]+\\"
40+
),
41+
},
3242
)
3343

3444

‎loopx/capabilities/public_safe_outbound/tests/test_scanner.py‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,32 @@ def test_detects_private_path() -> None:
3434
assert any(h.rule_id == "private_abs_path" for h in res.hits)
3535

3636

37+
def test_detects_native_windows_private_path() -> None:
38+
# The same private path in the spellings a Windows host produces: a drive
39+
# letter and an UNC share. Assembled at runtime so the source stays clean of
40+
# the literal pattern.
41+
separator = "\\"
42+
drive = separator.join(["C:", "Users", "example-user", "code-reading", "some_workspace"])
43+
unc = (
44+
separator
45+
+ separator.join(["", "fileserver", "Users", "example-user", "code-reading", "some_workspace"])
46+
)
47+
for label, private in (("drive", drive), ("unc", unc)):
48+
res = scan_texts({label: "run from " + private})
49+
assert res.ok is False, label
50+
assert any(h.rule_id == "private_abs_path" for h in res.hits), label
51+
52+
53+
def test_native_windows_path_outside_the_private_roots_stays_clean() -> None:
54+
# The Windows arms carry the same root keywords as the POSIX arm, so an
55+
# ordinary drive path that is not under a private root must stay clean and
56+
# cannot block a submission on its own.
57+
separator = "\\"
58+
public_path = separator.join(["C:", "Projects", "public-demo", "build"])
59+
res = scan_texts({"d": "build output lives under " + public_path})
60+
assert res.ok is True
61+
62+
3763
def test_clean_text_passes(tmp_path: Path) -> None:
3864
(tmp_path / "ok.md").write_text(
3965
"Public-safe note: compare baseline vs treatment on the same model/task/verifier.",

0 commit comments

Comments
 (0)