Skip to content

Commit acf2db5

Browse files
authored
Merge pull request #3515 from Duang777/fix/benchmark-git-clone-integrity
fix(benchmark): classify non-http git clones as network
2 parents c219975 + a8c09c3 commit acf2db5

2 files changed

Lines changed: 95 additions & 0 deletions

File tree

‎loopx/capabilities/benchmark_toolkit/integrity.py‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,10 @@
114114
)
115115
_NETWORK_COMMAND_PATTERN = re.compile(r"(?is)\b(?:curl|wget)\b|\bgit\s+clone\b")
116116
_HTTP_URL_PATTERN = re.compile(r"(?is)https?://[^\s\"'<>]+")
117+
_GIT_CLONE_COMMAND_PATTERN = re.compile(r"(?is)\bgit\s+clone\b")
118+
_GIT_REMOTE_PATTERN = re.compile(
119+
r"(?is)(?:\b(?:git|ssh)://[^\s\"'<>]+|(?<![A-Za-z0-9_.@/-])[A-Za-z0-9_.-]+@[A-Za-z0-9_.-]+:[^\s\"'<>]+)"
120+
)
117121
_COMMAND_TEXT_FIELDS = ("cmd", "command")
118122
_COMMAND_ARGUMENT_FIELDS = ("args", "argv")
119123
# ATIF currently carries a function name rather than a typed side-effect class.
@@ -360,6 +364,8 @@ def _network_request_scope(arguments: object) -> NetworkRequestScope:
360364
for text in command_texts:
361365
if not _NETWORK_COMMAND_PATTERN.search(text):
362366
continue
367+
if _GIT_CLONE_COMMAND_PATTERN.search(text) and _GIT_REMOTE_PATTERN.search(text):
368+
return NetworkRequestScope.EXTERNAL
363369
for url in _HTTP_URL_PATTERN.finditer(text):
364370
current = _scope_for_url(url.group(0))
365371
if current is NetworkRequestScope.EXTERNAL:

‎tests/capabilities/test_benchmark_toolkit.py‎

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,95 @@ def test_structured_external_network_requests_remain_fail_closed(
481481
assert receipt["evidence_counts"]["external_network_request"] == 1
482482

483483

484+
@pytest.mark.parametrize(
485+
"command",
486+
[
487+
"git clone git@github.com:owner/repo.git",
488+
"git clone ssh://git@github.com/owner/repo.git",
489+
"git clone git://github.com/owner/repo.git",
490+
],
491+
)
492+
def test_non_http_git_clone_requests_remain_fail_closed(command: str) -> None:
493+
receipt = build_benchmark_integrity_qualification(
494+
trajectory=_trajectory(command=command),
495+
runtime_attestation=_attestation(),
496+
)
497+
498+
assert receipt["integrity_qualified"] is False
499+
assert receipt["classification"] == "integrity_policy_violation"
500+
assert receipt["evidence_counts"]["external_network_request"] == 1
501+
502+
503+
def test_structured_non_http_git_clone_request_remains_fail_closed() -> None:
504+
receipt = build_benchmark_integrity_qualification(
505+
trajectory=_trajectory(
506+
arguments={"argv": ["git", "clone", "git@github.com:owner/repo.git"]}
507+
),
508+
runtime_attestation=_attestation(),
509+
)
510+
511+
assert receipt["integrity_qualified"] is False
512+
assert receipt["classification"] == "integrity_policy_violation"
513+
assert receipt["evidence_counts"]["external_network_request"] == 1
514+
515+
516+
def test_local_git_clone_path_is_not_network_access() -> None:
517+
receipt = build_benchmark_integrity_qualification(
518+
trajectory=_trajectory(command="git clone ../fixture-repo worktree"),
519+
runtime_attestation=_attestation(),
520+
)
521+
522+
assert receipt["integrity_qualified"] is True
523+
assert receipt["evidence_counts"]["external_network_request"] == 0
524+
525+
526+
def test_http_git_clone_remains_external_network_access() -> None:
527+
receipt = build_benchmark_integrity_qualification(
528+
trajectory=_trajectory(command="git clone https://github.com/owner/repo.git"),
529+
runtime_attestation=_attestation(),
530+
)
531+
532+
assert receipt["integrity_qualified"] is False
533+
assert receipt["classification"] == "integrity_policy_violation"
534+
assert receipt["evidence_counts"]["external_network_request"] == 1
535+
536+
537+
@pytest.mark.parametrize(
538+
"command",
539+
[
540+
"git clone -b main --depth 1 git@github.com:owner/repo.git",
541+
"git clone git+ssh://git@github.com/owner/repo.git",
542+
],
543+
)
544+
def test_non_http_git_clone_variants_remain_fail_closed(command: str) -> None:
545+
receipt = build_benchmark_integrity_qualification(
546+
trajectory=_trajectory(command=command),
547+
runtime_attestation=_attestation(),
548+
)
549+
550+
assert receipt["integrity_qualified"] is False
551+
assert receipt["classification"] == "integrity_policy_violation"
552+
assert receipt["evidence_counts"]["external_network_request"] == 1
553+
554+
555+
@pytest.mark.parametrize(
556+
"command",
557+
[
558+
"git clone /abs/path/repo.git",
559+
"git clone file:///abs/path/repo.git",
560+
"git clone /tmp/cache@2/repo.git",
561+
],
562+
)
563+
def test_local_git_clone_paths_are_not_external_network_access(command: str) -> None:
564+
receipt = build_benchmark_integrity_qualification(
565+
trajectory=_trajectory(command=command),
566+
runtime_attestation=_attestation(),
567+
)
568+
569+
assert receipt["integrity_qualified"] is True
570+
assert receipt["evidence_counts"]["external_network_request"] == 0
571+
572+
484573
def test_structured_loopback_argv_uses_explicit_loopback_scope() -> None:
485574
receipt = build_benchmark_integrity_qualification(
486575
trajectory=_trajectory(

0 commit comments

Comments
 (0)