T09 · Insecure Skill Coding Practices
Warning
- Location
- SKILL.md:494
- Finding
- Unredacted MCP Tool Parameters May Expose Secrets in Logs## Vulnerability Details **File Location**: `SKILL.md`, lines 494–498 **Vulnerability Type**: Sensitive-data exposure through indiscriminate parameter logging **Risk Level**: Medium **Vulnerable Code:** ```typescript server.tool("my_tool", description, schema, async (params) => { const requestId = crypto.randomUUID().slice(0, 8); console.error(`[${requestId}] my_tool called:`, JSON.stringify(params)); const start = Date.now(); ``` Related guidance at line 447 also recommends recording calls “with what params” without requiring redaction: ```markdown - [ ] Audit log: who called what tool, when, with what params ``` ### Technical Analysis The logging template serializes the complete MCP tool parameter object and writes it to standard error. Tool parameters may contain API keys, authorization tokens, passwords, session identifiers, personal information, document contents, or proprietary business data. Standard error is commonly collected by process supervisors, container runtimes, cloud platforms, and centralized logging services. Consequently, sensitive parameters can be retained beyond their intended lifetime, become visible to additional operators, or be transmitted to an external logging provider. The pattern conflicts with the Skill's own credential-protection guidance at line 444, which states that API keys and secrets must never appear in tool responses, but it does not extend equivalent protection to logs. This is a documentation and template-level flaw rather than evidence that this repository itself actively exfiltrates data. However, servers generated from the template can reproduce the vulnerability. ### Attack Path 1. An MCP server adopts the provided logging template. 2. A tool accepts a sensitive value, such as an access token, password, private document, or personal record. 3. A legitimate user or attacker invokes the tool and places that value in `params`. 4. `JSON.stringify(params)` seria ...[truncated 1114 chars]
- Remediation
- ## Remediation Suggestions 1. Do not log complete parameter objects. Log only operational metadata by default: ```typescript console.error(`[${requestId}] my_tool called`); ``` 2. If parameter logging is necessary, use an explicit allowlist of fields known not to contain sensitive information: ```typescript const auditFields = { itemId: params.itemId, operation: params.operation, }; console.error(`[${requestId}] my_tool called:`, auditFields); ``` 3. Implement recursive, case-insensitive redaction for keys such as `authorization`, `apiKey`, `token`, `secret`, `password`, `cookie`, `session`, and `credential`. Treat unknown fields as sensitive by default. 4. Never log request bodies, document contents, authentication headers, OAuth codes, or raw error objects that may embed request configuration. 5. Revise the audit checklist to require minimal metadata, redaction, access controls, retention limits, and a documented lawful purpose for each logged field. 6. Restrict log access according to least privilege, encrypt logs in transit and at rest, define short retention periods, and ensure secret rotation and incident-response procedures cover accidental logging. 7. Add automated tests that submit known marker secrets and verify that the markers do not appear in standard output, standard error, log files, or exported telemetry.
