@murk-security/runner-linux-arm64 0.8.0 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/harness CHANGED
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@murk-security/runner-linux-arm64",
3
- "version": "0.8.0",
3
+ "version": "0.8.1",
4
4
  "description": "MURK local runner (prebuilt harness + adapter) for linux/arm64. Installed automatically by @murk-security/cli.",
5
5
  "os": [
6
6
  "linux"
@@ -30,6 +30,7 @@ import json
30
30
  import os
31
31
  import re
32
32
  import signal
33
+ import socket
33
34
  import sqlite3
34
35
  import subprocess
35
36
  import sys
@@ -959,6 +960,23 @@ def _run_remediate(spec: dict, em: "Emitter") -> int:
959
960
  return 0
960
961
 
961
962
 
963
+ def _target_listening(origin: str, timeout: float = 6.0) -> bool:
964
+ """Whether something is listening at the origin's host:port (a quick TCP connect). A refused or
965
+ timed-out connect means the app isn't running there, so the scan would hunt against nothing and
966
+ report no findings -- which reads as 'found nothing' rather than 'nothing was there'. An
967
+ unparseable origin returns True (don't block on a parse failure)."""
968
+ try:
969
+ u = urlparse(origin if "//" in origin else "http://" + origin)
970
+ host = u.hostname or ""
971
+ port = u.port or (443 if u.scheme == "https" else 80)
972
+ if not host:
973
+ return True
974
+ with socket.create_connection((host, port), timeout=timeout):
975
+ return True
976
+ except Exception:
977
+ return False
978
+
979
+
962
980
  def main() -> int:
963
981
  ap = argparse.ArgumentParser()
964
982
  ap.add_argument("--spec", required=True)
@@ -1015,6 +1033,21 @@ def main() -> int:
1015
1033
  em.emit("run.completed", {"stop": "halt", "findings": 0, "ok": True,
1016
1034
  "message": "no findings with a reproduction recipe to retest"})
1017
1035
  return 0
1036
+ # Fail fast if a live target isn't actually up. Otherwise the whole hunt runs against a dead
1037
+ # origin and reports no findings, which reads as "the scanner found nothing" rather than
1038
+ # "nothing was running there to scan". The `murk scan` CLI pre-checks before booking a local
1039
+ # run; this covers hosted runs and is a backstop for local. Skippable for tests/dev.
1040
+ _live_origins = (spec.get("target") or {}).get("origins") or []
1041
+ if kind == "assess" and _live_origins and os.environ.get("BASIC_HARNESS_SKIP_REACHABILITY") != "1":
1042
+ if all(not _target_listening(o) for o in _live_origins):
1043
+ em.emit("run.failed", {
1044
+ "category": "target",
1045
+ "message": ("couldn't reach the target (" + ", ".join(_live_origins) + ") — is the "
1046
+ "application running and listening there? No scan was performed."),
1047
+ "stop": "unreachable",
1048
+ })
1049
+ return 4
1050
+
1018
1051
  goal = build_retest_brief(retest_findings) if kind == "retest" else build_brief(spec)
1019
1052
  rounds = (os.environ.get("BASIC_HARNESS_RETEST_ROUNDS", "1") if kind == "retest"
1020
1053
  else os.environ.get("BASIC_HARNESS_ROUNDS", "3"))