T09 · Insecure Skill Coding Practices
- Location
src/index.ts:139- Finding
Sensitive MCP Tool Arguments Disclosed Through Unfiltered Logging
- Content
View full analysis
Vulnerability Details
File Location:
src/index.ts, lines 139-141
Vulnerability Type: Sensitive data exposure through application logs
Risk Level: MediumVulnerable Code
ts private simulateCall(tool: string, args: Record<string, any>): any { // Simplified implementation console.log(`[SelfEvolvingSkill] ${tool}:`, args);Sensitive values can reach this logging statement from the execution interface at
src/index.ts, lines 243-250:ts const result = await this.server.call('skill_execute', { skill_id: params.skillId, context: params.context || {}, embedding: params.embedding, success: params.success !== false, value_realization: params.value !== undefined ? params.value : 1.0 });Technical Analysis
When the Python MCP server is unavailable,
MCPServer.call()invokessimulateCall(). The audited package does not contain the expectedcore/mcp_server.py, so this fallback is likely to be used in the supplied artifact.The fallback logs the complete
argsobject without field allowlisting, redaction, or sensitivity checks. Theskill_executeinterface permits arbitrary data incontextand also passes embeddings and skill identifiers. Callers may reasonably include confidential task content, credentials, access tokens, personal data, internal identifiers, or proprietary information in that context.Application logs commonly have broader and longer-lived access than the original request data. They may be retained in terminal histories, CI output, container logs, process supervisors, or centralized logging systems.
Attack Path
- The Python MCP server is absent or otherwise fails to start.
- Initialization silently enables the JavaScript simulation fallback.
- A user or upstream agent invokes
skill_executewith sensitive information incontextor another argument. MCPServer.call()forwards the complete argument object tosimulateCall().simulateCall()writes the complete obj ...[truncated 893 chars]
- Remediation
View remediation
Remediation Suggestions
-
Remove complete argument logging from
simulateCall():ts console.log(`[SelfEvolvingSkill] Simulating tool: ${tool}`); -
If diagnostics require argument metadata, use a strict allowlist and log only non-sensitive properties:
ts console.log('[SelfEvolvingSkill] Simulating tool', { tool, hasContext: Boolean(args.context), embeddingLength: Array.isArray(args.embedding) ? args.embedding.length : 0 }); -
Never log arbitrary
contextobjects, embeddings, authorization values, tokens, cookies, passwords, or user-supplied payloads. -
Add a centralized redaction function for all structured logging. Recursively redact keys such as
authorization,token,secret,password,cookie, andapiKey. -
Disable diagnostic logging by default in production and control it through an explicit logging-level configuration.
-
Avoid silently entering simulation mode when the expected server implementation is absent. Return a clear initialization error unless callers explicitly opt into fallback behavior.
-
Add automated tests that pass canary secrets through every MCP method and verify that no secret appears in standard output, standard error, or structured logs.
-
Apply least-privilege access controls and appropriate retention limits to all application and centralized logs.
-
