Skip to content

v0.7.87 — Audit iteration 3 (auth/SSRF/secret-leak + correctness/DoS)

Latest

Choose a tag to compare

@ginkida ginkida released this 30 Jun 11:27
· 4 commits to main since this release

v0.7.87 — Audit iteration 3 (auth/SSRF/secret-leak + correctness/DoS)

Third adversarial-audit sweep over v0.7.86 — API auth/IDOR, channels, kernel
scheduler/RBAC/workflows, memory/knowledge, types/config, MCP-server, and
structured-output/routing. 36 candidate findings (the 19-item iter-3 backlog
plus 17 fresh finder findings) were each gated behind an independent 3-lens
refute panel; 27 confirmed and fixed, 8 rejected. Full CI green
(macOS/Ubuntu/Windows test+check, clippy, fmt, cargo audit, secrets scan).
1758 tests passing.

Security

  • Auth bypass (HIGH): with no API key configured, the localhost gate
    trusted a spoofable X-Forwarded-For from any private-net / Docker-bridge
    peer — so a sibling container or LAN host could send
    X-Forwarded-For: 127.0.0.1 and obtain unauthenticated Owner. The gate now
    uses the real transport peer IP (ConnectInfo), never forwarded headers.
  • SSRF via redirect (HIGH×2): the A2A client and cron-webhook delivery
    followed HTTP redirects without re-checking — a public URL could 3xx-redirect
    to 127.0.0.1 / 169.254.169.254 / RFC1918. Both now re-validate every hop
    (matching the web-fetch/browser fix from v0.7.86).
  • PSK leak (HIGH): the RHP HMAC shared_secret was serialized in plaintext
    through the in-process MCP config_get path. Now #[serde(skip_serializing)]
    like api_key/proxy.password.
  • MCP privilege escalation: schedule_create/schedule_delete dropped from
    the safe-default allowlist (they persist Admin-gated recurring agent turns).
  • MCP file read: file_read/file_list/file_stat are confined to the
    agent-workspaces dir instead of the daemon's process CWD (which exposed
    config.toml/.env/.ssh to a remote MCP caller).
  • Telegram token leak: bot token redaction now also covers the
    /file/bot{token}/ download-URL shape and the channel-agnostic bridge log
    sites where reqwest errors escape via ?.

Correctness

  • Cost quota over-counted ~24×: the hourly window compared an RFC3339
    string lexically against SQLite datetime(), collapsing "last hour" into a
    midnight-resetting "today". Normalized with datetime(timestamp).
  • Cron: update_job (PUT) now enforces the same caps as create (no
    fire-every-tick DoS / chrono overflow); the IANA timezone is honored
    (chrono-tz) instead of silently firing UTC; unparseable / never-matching
    expressions are rejected at create/update; crash-orphaned claimed jobs are
    rescheduled on load instead of stuck forever.
  • Workflows: runs no longer leak as perpetually Running on
    agent-resolution failure or caller timeout (which defeated the eviction cap);
    definition persistence serializes via a mutex + unique temp file (no
    concurrent-write corruption / lost definitions).
  • Knowledge graph: query_graph honors max_depth (breadth-first
    neighborhood traversal — it was single-hop only); the full-graph view reports
    the true edge total; list_entities is capped.
  • Vector recall: embedding queries no longer pre-select the candidate pool
    by recency, so a best-matching but not-recently-accessed memory is actually
    returned.
  • Session search: a Unicode-aware lower UDF makes case-insensitive search
    match capitalized non-ASCII (Cyrillic etc.); pre-v8 message_count fallback
    fixed.
  • OpenAI-compat: an unknown model returns a deterministic 404 (was an
    arbitrary agent); streaming tool_call indices stay monotonic across loop
    iterations (no client-side merge corruption); image content is rejected
    rather than silently dropped.
  • Config: exec_policy.timeout_secs = 0 is clamped to 30 (a 0 made every
    shell_exec time out instantly); max_restarts is now enforced in
    restart_agent.

Deferred: mid-turn budget enforcement — the correct fix needs incremental
metering plus a mid-turn turn-cutoff, a behavior change that interacts with the
hourly-window fix above; out of scope for this hardening batch.