collector: tag CVEs yours/upstream/update + stop flagging the edge
Build and push soc-collector / build (push) Successful in 7s
Build and push soc-collector / build (push) Successful in 7s
cve: each image now carries an UPDATE STATUS in its title — [yours] (git.skui.io image, fix in its repo), [update] (third-party, a NEWER image is published -> pull it), or [upstream] (already running the latest published image -> clears only when the maintainer rebuilds). 'Fixable' just means a patched package exists, not that you can apply it; the status makes that explicit, and actionable findings now sort above the can't-touch ones. config: the designated edge (SOC_EDGE, default 'traefik') is allowed to own 0.0.0.0:80/443 -- that is its job -- so it's reported as good rather than a false-positive finding.
This commit is contained in:
+17
-4
@@ -1,15 +1,23 @@
|
||||
"""Config-drift source: read-only Docker socket -> 0.0.0.0 binds, privileged, rw-socket mounts."""
|
||||
"""Config-drift source: read-only Docker socket -> 0.0.0.0 binds, privileged, rw-socket mounts.
|
||||
|
||||
The designated edge proxy (SOC_EDGE, default 'traefik') is SUPPOSED to own 0.0.0.0:80/443 —
|
||||
that's its whole job — so its public binds are reported as good, not flagged (false positive)."""
|
||||
import os
|
||||
|
||||
from soc import finding
|
||||
|
||||
from . import _docker
|
||||
|
||||
# Containers that are the public edge: allowed to bind 0.0.0.0 (they front the estate).
|
||||
EDGE = {x.strip() for x in os.environ.get("SOC_EDGE", "traefik").replace(";", ",").split(",") if x.strip()}
|
||||
|
||||
|
||||
def run():
|
||||
if not _docker.available():
|
||||
return None # socket not mounted -> skip
|
||||
conts = _docker.get("/containers/json") or []
|
||||
|
||||
findings = []
|
||||
findings, edge_ok = [], []
|
||||
for c in conts:
|
||||
name = (c.get("Names") or ["?"])[0].lstrip("/")
|
||||
cid = c.get("Id", "")[:12]
|
||||
@@ -25,7 +33,9 @@ def run():
|
||||
for b in (binds or []):
|
||||
if b.get("HostIp") in ("0.0.0.0", "::", ""):
|
||||
exposed.append(f"{b.get('HostIp') or '0.0.0.0'}:{b.get('HostPort')}->{port}")
|
||||
if exposed:
|
||||
if exposed and name in EDGE:
|
||||
edge_ok.append(f"{name} ({'; '.join(exposed)})") # the edge — public by design
|
||||
elif exposed:
|
||||
findings.append(finding(
|
||||
f"drift-bind-{name}", "high", f"{name} publishes ports on all interfaces",
|
||||
host=name, evidence="; ".join(exposed),
|
||||
@@ -47,8 +57,11 @@ def run():
|
||||
impact=["the container can control the host's Docker = host root"],
|
||||
fix=["mount it :ro, or put a scoped socket-proxy in front"]))
|
||||
|
||||
good = [f"edge {e} binds 0.0.0.0:80/443 by design (allowed)" for e in edge_ok]
|
||||
if not findings and not good:
|
||||
good.append("No 0.0.0.0 binds, privileged, or rw-socket containers")
|
||||
return {
|
||||
"scope": f"{len(conts)} container(s)",
|
||||
"findings": findings,
|
||||
"good": [] if findings else ["No 0.0.0.0 binds, privileged, or rw-socket containers"],
|
||||
"good": good,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user