aegis-rex 1.5.1 → 1.5.2

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/vendor/rex.py +38 -17
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aegis-rex",
3
- "version": "1.5.1",
3
+ "version": "1.5.2",
4
4
  "description": "Headless-drivable security auditor for Linux, macOS and Windows. Runs a 17-check local audit and can be driven by an AI agent (--capabilities / --audit --json / --fix). npm is the distribution channel; the tool itself is dependency-free Python.",
5
5
  "bin": {
6
6
  "rex": "bin/rex.js"
package/vendor/rex.py CHANGED
@@ -118,7 +118,7 @@ IS_LINUX = _OS == "Linux"
118
118
  # ============================================================
119
119
  # KONFIGURATION
120
120
  # ============================================================
121
- VERSION = "1.5.1"
121
+ VERSION = "1.5.2"
122
122
  APP_NAME = "ÆGIS Security Audit"
123
123
 
124
124
  # Lines emitted by find(1)/stat(1) *about* a path rather than *as a result*.
@@ -714,24 +714,45 @@ class AuditEngine:
714
714
  return status, out or "No world-accessible binaries found in System32"
715
715
 
716
716
  else: # Linux + macOS
717
- safe_paths = ["/usr", "/bin", "/sbin", "/lib", "/lib64", "/opt"]
717
+ # Where a distro's package manager is allowed to drop a
718
+ # SUID/SGID binary. A stock Ubuntu box carries ~30 helpers in
719
+ # /usr/bin and /usr/lib (sudo, passwd, mount, su, pkexec …);
720
+ # reporting that inventory as a defect buries the one binary
721
+ # that was actually put there by hand. So the bit itself is
722
+ # inventoried, and only *where* it was found decides the status.
723
+ managed_dirs = (
724
+ "/usr/bin/", "/usr/sbin/", "/usr/lib/", "/usr/lib32/",
725
+ "/usr/lib64/", "/usr/libexec/", "/bin/", "/sbin/",
726
+ "/lib/", "/lib32/", "/lib64/",
727
+ )
718
728
  if IS_MAC:
719
- safe_paths = ["/usr", "/bin", "/sbin", "/opt"]
720
- existing = [p for p in safe_paths if os.path.isdir(p)]
721
- out = cmd(["find"] + existing + ["-perm", "/6000", "-type", "f"], timeout=20)
729
+ managed_dirs = ("/usr/bin/", "/usr/sbin/", "/usr/lib/",
730
+ "/usr/libexec/", "/bin/", "/sbin/", "/System/")
731
+ # /home is deliberately absent: a recursive scan of home dirs
732
+ # exceeded 120s on a real machine, and an audit that stalls is
733
+ # worse than one with a stated scope. The remaining roots are
734
+ # sub-second.
735
+ scan_roots = ["/usr", "/bin", "/sbin", "/lib", "/lib64",
736
+ "/usr/local", "/opt", "/tmp", "/var/tmp"]
737
+ existing = [p for p in scan_roots if os.path.isdir(p)]
738
+ out = cmd(["find"] + existing + ["-perm", "/6000", "-type", "f"], timeout=25)
722
739
  real, noise = self._split_noise(out)
723
- if real:
724
- lines = real[:30]
725
- out = "\n".join(lines)
726
- if len(lines) == 30:
727
- out += "\n[truncated at 30 results]"
728
- if noise:
729
- out += f"\n({len(noise)} path(s) not readable, skipped)"
730
- return "warn", out
731
- note = "No SUID/SGID files found in system dirs"
732
- if noise:
733
- note += f" ({len(noise)} path(s) not readable, skipped)"
734
- return "ok", note
740
+ managed = [f for f in real if f.startswith(managed_dirs)]
741
+ unexpected = [f for f in real if not f.startswith(managed_dirs)]
742
+ suffix = f"\n({len(noise)} path(s) not readable, skipped)" if noise else ""
743
+ if unexpected:
744
+ lines = unexpected[:30]
745
+ body = "\n".join(lines)
746
+ if len(unexpected) > 30:
747
+ body += f"\n[truncated at 30 of {len(unexpected)} results]"
748
+ if managed:
749
+ body += (f"\n({len(managed)} SUID/SGID binary(ies) under "
750
+ f"distro-managed paths, expected inventory)")
751
+ return "warn", body + suffix
752
+ if managed:
753
+ return "ok", (f"{len(managed)} SUID/SGID binaries found, all under "
754
+ f"distro-managed paths (expected inventory)" + suffix)
755
+ return "ok", "No SUID/SGID files found in scanned paths" + suffix
735
756
 
736
757
  # ── World-Writable Files ──────────────────────────────
737
758
  elif section == "World-Writable Files":