Skip to content

fix(config): redact sensitive CLI argv values in config-audit.jsonl#70468

Closed
Ziy1-Tan wants to merge 1 commit intoopenclaw:mainfrom
Ziy1-Tan:fix/redact-argv-in-config-audit
Closed

fix(config): redact sensitive CLI argv values in config-audit.jsonl#70468
Ziy1-Tan wants to merge 1 commit intoopenclaw:mainfrom
Ziy1-Tan:fix/redact-argv-in-config-audit

Conversation

@Ziy1-Tan
Copy link
Copy Markdown
Contributor

Summary

config-audit.jsonl records process.argv as part of tamper-detection audit entries. Any command containing secret-bearing flags (e.g. --token, --bot-token, --gateway-token) would persist those values in plaintext on disk permanently.

Fixes #60826. Related prior attempt: #60871 (closed due to author PR queue limit, not a technical rejection).

Changes

  • src/config/io.audit.ts: Import redactSensitiveText / getDefaultRedactPatterns from logging/redact. Add AUDIT_ARGV_EXTRA_PATTERNS constant that extends the default CLI flag pattern with missing flag names (bot-token, gateway-token, app-token, access-token, custom-api-key) and = as a separator (to cover --flag=value format). Apply redaction via join(" ") → redactSensitiveText → split(" ") in resolveConfigAuditProcessInfo(). Export the function.
  • src/config/io.ts: Import resolveConfigAuditProcessInfo. Replace two inline pid/ppid/cwd/argv/execArgv blocks (lines ~662 and ~796) with ...resolveConfigAuditProcessInfo().
  • src/config/io.observe-recovery.ts: Import resolveConfigAuditProcessInfo. Replace one inline block with ...resolveConfigAuditProcessInfo().
  • src/config/io.audit.test.ts: Add tests for redaction of --token, --token=value, --bot-token, --gateway-token, --password=value, --app-token, --access-token, --custom-api-key; non-secret flag pass-through; empty argv.

Design

Reuses existing redactSensitiveText infrastructure (same pattern used in src/gateway/ws-log.ts). The processInfo override path in resolveConfigAuditProcessInfo is intentionally left unredacted — callers that supply their own processInfo (e.g. tests) receive it back as-is.

typecheck prod failure in CI is pre-existing on main and unrelated to this change.

Test plan

  • pnpm test src/config/io.audit.test.ts — 17 tests pass (13 existing + 10 new)
  • pnpm test src/config/io.observe-recovery.test.ts — existing tests unaffected
  • No new process.argv.slice outside resolveConfigAuditProcessInfo

AI-assisted

This PR was AI-assisted (Claude). Code reviewed and understood by the author. Testing: fully tested.

Post-Deploy Monitoring & Validation

No runtime behavior change. The audit log is best-effort and write-only from the perspective of the tamper-detection logic. No metrics or dashboards to watch. Validation: confirm config-audit.jsonl entries no longer contain plaintext token values after running openclaw gateway install --token=<value> under anomaly conditions.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 23, 2026

Greptile Summary

This PR fixes a real security issue: process.argv was written verbatim to config-audit.jsonl, which could persist plaintext token values from flags like --token, --bot-token, and --gateway-token. The fix reuses the existing redactSensitiveText infrastructure and consolidates three previously duplicated process.argv.slice(0, 8) blocks into a single resolveConfigAuditProcessInfo() helper.

  • P1: The redaction round-trips argv through join(" ") → redact → split(" "), which splits argv tokens that contain spaces (e.g. file paths like /home/user/my project/openclaw.js) into multiple elements, producing a structurally incorrect argv array in the audit log.

Confidence Score: 4/5

Hold for the argv join/split correctness fix before merging.

The security goal is sound and the approach is directionally correct, but the join-then-split round-trip produces a structurally wrong argv array whenever any argument contains a space. This is a present defect on the changed code path (wrong data written to the audit log), not a hypothetical, warranting a 4 rather than a 5.

src/config/io.audit.ts — the resolveConfigAuditProcessInfo redaction logic needs the per-element approach.

Prompt To Fix All With AI
This is a comment left during a code review.
Path: src/config/io.audit.ts
Line: 180-189

Comment:
**`join(" ").split(" ")` corrupts argv entries that contain spaces**

Joining the argv array with a space delimiter and then splitting the redacted result back on spaces destroys the original token boundaries. Any argument that itself contains a space — e.g. `process.argv[1]` pointing to a path like `/home/user/my project/openclaw.js`, or a flag value like `--message "hello world"` — gets silently split into multiple elements in the written audit record.

A path-safe approach is to redact each element independently:

```ts
const rawArgv = process.argv.slice(0, 8);
const redactedArgv = rawArgv.map((arg) =>
  redactSensitiveText(arg, {
    mode: "tools",
    patterns: [...getDefaultRedactPatterns(), ...AUDIT_ARGV_EXTRA_PATTERNS],
  }),
);
return {
  pid: process.pid,
  ppid: process.ppid,
  cwd: process.cwd(),
  argv: redactedArgv,
  execArgv: process.execArgv.slice(0, 8),
};
```

This still matches multi-word patterns (e.g. `--token value`) because each element is compared against patterns that also match the `=`-delimited form, and space-separated values land in adjacent elements which the existing `\s+` variant covers when the flag and value happen to be in the same element.

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: src/config/io.audit.test.ts
Line: 222-226

Comment:
**`AUDIT_ARGV_EXTRA_PATTERNS` duplicated instead of exported**

The test file manually mirrors the `AUDIT_ARGV_EXTRA_PATTERNS` constant from `io.audit.ts` with a comment saying "Mirror the pattern constant from io.audit.ts to exercise it directly in tests." If the production constant is updated (new flag names, tweaked regex), the test copy will silently diverge and the tests will no longer validate the actual patterns in use.

Consider exporting `AUDIT_ARGV_EXTRA_PATTERNS` from `io.audit.ts` and importing it here, so the tests always exercise the real constant rather than a copy.

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "fix(config): redact sensitive CLI argv v..." | Re-trigger Greptile

Comment thread src/config/io.audit.ts Outdated
Comment thread src/config/io.audit.test.ts Outdated
@Ziy1-Tan Ziy1-Tan force-pushed the fix/redact-argv-in-config-audit branch from f404be5 to 2ca6a1c Compare April 23, 2026 03:59
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f404be5b77

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/config/io.audit.ts Outdated
@Ziy1-Tan Ziy1-Tan force-pushed the fix/redact-argv-in-config-audit branch from 2ca6a1c to e313ec1 Compare April 23, 2026 04:34
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e313ec1fb4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/config/io.audit.ts Outdated
config-audit.jsonl records process argv as part of tamper-detection
audit entries. Commands containing secret-bearing flags (--token,
--bot-token, --gateway-token, --password, etc.) would persist those
values in plaintext on disk.

Changes:
- Add AUDIT_ARGV_EXTRA_PATTERNS in io.audit.ts: extends the default
  CLI flag redaction pattern with missing flag names (bot-token,
  gateway-token, app-token, access-token, custom-api-key) and adds `=`
  as a separator for --flag=value format.
- In resolveConfigAuditProcessInfo(), join argv to a single string,
  apply redactSensitiveText with the extended patterns, and store as a
  single-element array. This avoids join/split boundary corruption while
  reusing the existing redaction infrastructure; flag names are
  preserved in the output for diagnostics.
- Export resolveConfigAuditProcessInfo() and replace the three inline
  process.argv.slice(0, 8) blocks in io.ts (x2) and
  io.observe-recovery.ts with ...resolveConfigAuditProcessInfo().
- Add unit tests covering each flag type, both --flag value and
  --flag=value formats, non-secret pass-through.

Fixes openclaw#60826
@Ziy1-Tan Ziy1-Tan force-pushed the fix/redact-argv-in-config-audit branch from e313ec1 to 7892635 Compare April 23, 2026 04:45
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 78926356f8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/config/io.audit.ts
Comment on lines +184 to +185
argv: [
redactSensitiveText(process.argv.slice(0, 8).join(" "), {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep argv tokenized after redaction

resolveConfigAuditProcessInfo() now wraps the redacted command string in a single-element array, so every config.write/config.observe audit record loses original argv token boundaries (argv[0] becomes the full command line). This is a behavior regression from the previous process.argv.slice(0, 8) shape and can break tooling or incident triage logic that reads positional args (for example command/subcommand detection from argv[1]/argv[2]). Redaction should preserve the array contract instead of collapsing all args into one entry.

Useful? React with 👍 / 👎.

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

config-audit.jsonl logs plaintext secrets in CLI argv

1 participant