Skip to content

Bug: @query audit log leaks secrets in command text and stderr #137

@tcconnally

Description

@tcconnally

Severity: 🔴 Critical (silent secret leak in audit log)

src/perseus/directives/query.py writes the executed command verbatim to audit_log.jsonl via audit_event(... command=cmd[:500] ...). The audit log path does NOT pipe values through redact_text. Render-time redaction only applies to the final rendered output, not to audit fields.

If a user writes @query "curl -H 'Authorization: Bearer ghp_…'", the rendered output is correctly redacted, but ~/.perseus/audit_log.jsonl contains the raw bearer token forever.

Affected paths (in directives/query.py)

  • Line ~91: audit_event(cfg, "shell_exec", command=cmd[:500], ...) — leaks cmd
  • Line ~119: header = f"> ⚠ \@query` exited {exit_code}: `{cmd}`\n\n"` — leaks cmd (rendered, but later in the pipeline than audit)
  • Line ~121: body = stdout or stderr or "(no output)" — leaks stderr containing tokens
  • Line ~126: return f"> (no output from \{cmd}`)"` — leaks cmd
  • Line ~161: return f"> ⚠ \@query` timed out ({timeout}s): `{cmd}`"` — leaks cmd
  • Line ~165: return f"> ⚠ \@query` error: {exc}"` — exc.args often includes cmd

Repro

cat > .perseus/context.md <<'PCM'
@query "echo 'AKIAIOSFODNN7EXAMPLE'"
PCM
perseus render
grep AKIA ~/.perseus/audit_log.jsonl
# Expected: nothing
# Actual:   audit entry with raw AKIA key

Suggested fix

  1. In audit.py::audit_event, pipe every field value (or at least command, args, error, stdout, stderr) through redact_text before writing.
  2. In directives/query.py, also call redact_text(cmd, cfg) and redact_text(stderr, cfg) before interpolating into error messages.

Acceptance criteria

  • Test: @query with an AWS key in the command produces an audit entry with [REDACTED:aws_access_key_id] in place of the key.
  • Same for timeout, error, and exit-nonzero paths.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions