Plaintext secrets are written into VS Code extension host output logs
Type: <b>Bug</b>
Hello VS Code Security Team,
I’m reporting a high-severity security issue involving the VS Code extension host logging pipeline and an AI assistant integration that also auto-applies command allow/deny rules.
What’s happening
- Plaintext secrets are written into VS Code extension host logs
- The assistant applies “permission updates” (allow rules) for shell commands.
- Those permission updates are logged by the extension host.
- When a command includes an inline secret (e.g., PGPASSWORD, MCP keys, Authorization headers), the secret value is stored in plaintext in the underlying log file.
- The UI may truncate the displayed line, but the actual log file retains the full command string.
- Allowlist/denylist is saved into the user’s repository and can be git-tracked
- The integration persists allow/deny rules into a repo directory (e.g., a “.claude/” area).
- In practice this becomes git-tracked unless the user explicitly adds the path to .gitignore.
- If secrets are ever embedded into those rules (even once), they can become committed, pushed, and replicated.
Why this is severe
- It exposes database passwords, MCP keys, and API tokens in plaintext on disk and potentially in git history.
- It disproportionately harms early-stage teams and young developers who are more likely to approve “quick” commands and more likely to commit whatever appears in their repo scaffolding.
- It creates long-lived blast radius: logs, backups, git commits, PRs, and forks.
Sanitized evidence (extension host log patterns)
Below are redacted excerpts showing the relevant structure and where the secrets appear. I am intentionally removing all real secret values and any identifying hostnames.
- Extension host log shows permission updates containing secret-bearing patterns:
[info] From <assistant>: <timestamp> [DEBUG] Applying permission update: Adding <N> allow rule(s) to destination 'projectSettings':
"...",
"Bash(PGPASSWORD=:*)",
"Bash(psql:*)",
"Bash(curl:*)",
"..."
- Extension host log shows allow rules that include inline env-var secrets (values redacted):
"Bash(PGPASSWORD='REDACTED' psql:*)"
"Bash(MCP_API_KEY='REDACTED' node <script>:*)"
"Bash(curl ... -H "Authorization: Bearer REDACTED" ...)"
- Extension host log shows allow rules that include secret-bearing HTTP headers (values redacted):
"Bash(curl -X POST https://<domain>/... -H "Content-Type: application/json" -H "X-API-Key: REDACTED" -d '{...}')"
- Permission update indicates the allow/deny rules are stored as project settings (repo-local persistence):
[DEBUG] Applying permission update: destination 'projectSettings'
Impact observed in real workflows
- I have had to scrub my repository multiple times due to secrets being written into generated .md/.sh outputs and/or config files during “report generation” or scaffolding flows.
- After cleanup and rotation, I’m currently troubleshooting authentication failures that appear to stem from the after-effects of this repeated secret exposure and subsequent revocations/rotations.
Requested remediation from VS Code
- Prevent secrets from being written to extension host logs
- Introduce automatic secret redaction for:
- PGPASSWORD / database URLs containing user:pass@
- MCP keys / API keys / tokens (common header patterns)
- Authorization headers (Bearer, Basic, etc.)
- Ensure redaction occurs before data hits disk.
- Protect repo-local settings files
- If an integration persists allow/deny rules into the workspace:
- Default these files to non-git-tracked or warn prominently
- Provide a built-in “auto-add to .gitignore” safeguard
- Prevent literal secret values from being written into any workspace file
- UX safety rails
- When users approve a command that appears to contain a secret, show a warning and recommend safer mechanisms:
- .pgpass, pg_service.conf + .pgpass
- prompting for passwords
- OS keychain / secret store injection
I can provide (securely)
- Full redacted logs showing the exact extension host output source and file location.
- Minimal reproduction steps using placeholder strings (no real secrets).
- VS Code version, OS, and extension versions involved.
Please advise the secure channel for submitting the redacted artifacts.
Regards,
Lan Onasis
Extension version: 2.1.77
VS Code version: Code 1.111.0 (Universal) (ce099c1ed25d9eb3076c11e4a280f3eb52b4fbeb, 2026-03-06T23:06:10Z)
OS version: Darwin arm64 25.3.0
Modes:
Connection to 'tunnel+srv896342' could not be established
<details>
<summary>System Info</summary>
|Item|Value|
|---|---|
|CPUs|Apple M3 (8 x 2400)|
|GPU Status|2d_canvas: enabled<br>GPU0: VENDOR= 0x106b [Google Inc. (Apple)], DEVICE=0x0000 [ANGLE (Apple, ANGLE Metal Renderer: Apple M3, Version 26.3.1 (Build 25D2128))], DRIVER_VENDOR=Apple, DRIVER_VERSION=26.3.1 ACTIVE<br>Machine model name: Mac<br>Machine model version: 15.12<br>direct_rendering_display_compositor: disabled_off_ok<br>gpu_compositing: enabled<br>multiple_raster_threads: enabled_on<br>opengl: enabled_on<br>rasterization: enabled<br>raw_draw: disabled_off_ok<br>skia_graphite: enabled_on<br>trees_in_viz: disabled_off<br>video_decode: enabled<br>video_encode: enabled<br>webgl: enabled<br>webgl2: enabled<br>webgpu: enabled<br>webnn: disabled_off|
|Load (avg)|4, 4, 3|
|Memory (System)|8.00GB (0.14GB free)|
|Process Argv|--crash-reporter-id d097f59f-bbad-4568-96f0-958fd5458fca|
|Screen Reader|yes|
|VM|0%|
Connection to 'tunnel+srv896342' could not be established
</details>
<!-- generated by issue reporter -->
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗