Static Application Security Assessment

smf-praxis — a governed agent,
audited at the seams

smfworks/smf-praxis · Python 3.10+ · dependency-free core · container runtime
Method static, manual source review Modules covered 11 primary files Findings 19 (0 critical · 3 high · 6 medium · 6 low · 4 info) Classification CWE-mapped

SECTION 01Executive Summary

Praxis shows unusually strong security design intent for an autonomous-agent project — a governance broker, approval queues, a durable kill-switch, path-traversal defenses and a pluggable sandbox. The residual risk concentrates at its network perimeter: an HTTP-only control plane whose authentication guards only mutating routes, unvalidated outbound egress, and several fail-open downgrades in the sandbox layer.

Composite risk score
0/100
ELEVATED

Priority recommendations

  1. Require the auth token on every API route — including reads — whenever the daemon binds beyond loopback, and ship TLS (or mandate an authenticating reverse proxy) before any non-loopback deployment.
  2. Add an egress guard: validate scheme (https) and block private/loopback/link-local IP literals in gateways._post_json, fetch_url and the search backends; today a crafted webhook target is a ready-made SSRF and exfiltration channel.
  3. Make sandbox backend selection fail-closed: a requested ssh/docker backend that is unavailable or misconfigured must error, not silently downgrade to local.
  4. Scrub the environment passed to local sandbox execution — the current {**os.environ, …} hands every provider API key to any approved shell command.
  5. Restrict praxis.json to 0600 after the auth token is minted into it, and add failed-attempt throttling to token verification.

Scope, strengths & limitations

  • Durable, store-backed kill-switch survives daemon restarts
  • Cross-platform path-traversal defense in real_tools._resolve
  • Upload size caps, SSE queue bounds, idempotency-receipt limits
  • Non-root container (uid 10001), read-only rootfs sandbox, dropped caps
  • Dashboard HTML (~6,100 lines) and 6 modules were truncated — dynamic testing of the SPA (XSS, CSP) is still required
  • Mock M365 tools reviewed for risk misclassification only

SECTION 02Findings Ledger

Ranked by severity, each with file-level evidence and a concrete fix. Filter by severity, search by text, or click a heatmap cell in Section 04 to cross-filter by module and category.

SECTION 03Dependency & Supply-Chain Graph

The core installs nothing — its real attack surface is optional extras. Drag nodes, scroll to zoom, drag the canvas to pan, click a node for its constraint and risk notes. Amber-ringed nodes carry elevated supply-chain risk.

core (stdlib-only) optional extra elevated supply-chain risk
Select a node

Click any node in the graph to inspect its version constraint, why it is pulled in, and any supply-chain observations.

wheel · drag / wheel-zoom / click

SECTION 04Risk Heatmap

Risk concentration by module and vulnerability category. Intensity reflects the highest-severity finding mapped to that cell. Click any populated cell to jump to the matching findings; hover for detail.

high (3) medium (2) low (1) verified control (✓) click cell → filters Section 02

SECTION 05Recommended Fixes

Minimal, drop-in patches against the reviewed sources. Red lines are removed, green lines are added. Each diff references its finding IDs.