Skip to content

Observability plane bypasses redactSecrets() — secrets can land in local ledgers/receipts (MEDIUM) #31

Description

@FerroxLabs

Tracked from the v1.6.4 cross-audit (dimension b, adversarially verified). The MEMORY write path correctly runs redactSecrets() (mcp-server/src/redactor.js) on every ingest, but the OBSERVABILITY plane does not — several surfaces persist raw command lines / prompts / child output that can contain tokens, several with default 0644 perms.

Confirmed instances:

  1. Observation ledgerscripts/observation/titleize.js (Bash titles = first ~80 chars of the raw command line; UserPromptSubmit titles = first 80 chars of the raw prompt) → scripts/observation/ledger.js appendFileSync(JSONL_PATH, ...) with no mode (0644) under a default-mode ~/.ijfw. A command like OPENAI_API_KEY=sk-... npm test or curl -H "Authorization: Bearer <tok>" persists the token in the title, indefinitely (10 rotated archives).
  2. ijfw_run sandboxmcp-server/src/sandbox.js spawns with full process.env; when output >40 lines, writeToSandbox writes the raw ANSI-stripped output + full command string to ~/.ijfw/session-sandbox/<label>.{txt,json} with no redaction (dir 0700/files 0600, 24h TTL — same-user exposure).
  3. profile edit-deltamcp-server/src/profile/capture.js EDIT_PII_PATTERNS scrubs assigned secrets but misses BARE key literals (const k = "sk-ant-...", a ghp_ in a URL) in cited_span (cap 160 chars); appended to <project>/.ijfw/.session-edits.jsonl (0644).
  4. cross-audit receiptsmcp-server/src/cross-orchestrator.js stderrSnip (child-CLI stderr, 500 chars) lands in <project>/.ijfw/receipts/cross-runs.jsonl (0644) unredacted (mitigated: per-auditor env allowlist, so a child echoes only its own key).

Root cause: one plane enforces redactSecrets(), the other doesn't. Fix direction: route these four sinks through redactSecrets() before write, and set mode 0o600 on the ledger/JSONL appends. Watch item (no current leak): observability/trace-id.js traceEnv() returns full process.env — no spawn consumers today, but a loaded gun; allowlist it.

Severity MEDIUM (local same-user / backup exposure, not remote). Not fixed in the v1.6.4 audit loop (CRITICAL/HIGH were prioritized); filing so it's tracked.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions