T09 · Insecure Skill Coding Practices
- Location
SKILL.md:17- Finding
Unredacted Tool Parameters and Results Exposed in Audit Logs
- Content
View full analysis
{ const entry = { ts: new Date().toISOString(), event: "before_tool_call", tool: event.tool.name, params: JSON.stringify(event.tool.params).slice(0, 500), session: ctx.sessionKey, user: ctx.session?.senderId || 'unknown' }; console.log("[AUDIT]", JSON.stringify(entry)); return {}; }); api.registerHook("after_tool_call", async ({ event, ctx }) => { const entry = { ts: new Date().toISOString(), event: "after_tool_call", tool: event.tool.name, result: String(event.result).slice(0, 200), error: event.error?.message || null, duration: event.durationMs, session: ctx.sessionKey }; console.log("[AUDIT]", JSON.stringify(entry)); return {}; }); ``` The separately documented redaction function is: ```javascript function redactSensitive(obj) { const sensitive = ['apiKey', 'token', 'password', 'secret']; for (const key of Object.keys(obj)) { if (sensitive.some(s => key.toLowerCase().includes(s))) { obj[key] = '[REDACTED]'; } } return obj; } ``` ### Technical Analysis The hooks serialize tool parameters and results directly into console logs. Tool calls can contain API credentials, authorization headers, passwords, private file content, personal information, command arguments, or other sensitive values. The documented `redactSensitive` function is not invoked by either hook. Consequently, the statement that sensitive fields are automatically redacted does not match the demonstrated implementation. Even if the function were invoked, it would provide incomplete protection because: - It examines only top-level object keys. - It does not recursively process nested objects or arrays. - It relies ...[truncated 2112 chars]- Remediation
View remediation
{ console.log("[AUDIT]", JSON.stringify({ ts: new Date().toISOString(), event: "before_tool_call", tool: event.tool.name })); return {}; }); api.registerHook("after_tool_call", async ({ event }) => { console.log("[AUDIT]", JSON.stringify({ ts: new Date().toISOString(), event: "after_tool_call", tool: event.tool.name, success: !event.error, duration: event.durationMs })); return {}; }); ``` ]]>
