T09 · Insecure Skill Coding Practices
Error
- Location
- index.ts:925
- Finding
- Discord Webhook Credentials Exposed in Tool Responses## Vulnerability Details **File Location**: `index.ts`, lines 925–933 **Vulnerability Type**: Sensitive credential exposure **Risk Level**: High ### Vulnerable Code ```ts webhooks: hooks.map((hook: any) => ({ id: hook.id, name: hook.name, channelId: hook.channelId, url: hook.url, })), ``` The guild-level `webhook-list` branch immediately following this code returns the same sensitive `hook.url` property. ### Technical Analysis Discord webhook URLs contain an identifier and secret token that authorize unauthenticated webhook operations. They must therefore be treated as credentials rather than ordinary resource metadata. The `webhook-list` action serializes each complete webhook URL into the tool response. The shared `json()` response helper places the data in both textual tool content and the `details` field. This can expose the credential to the language model context, conversation history, tool telemetry, application logs, or downstream integrations. Listing webhooks only requires non-secret metadata such as the webhook ID, name, and channel ID. Returning the credential-bearing URL exceeds the minimum data exposure necessary for the declared listing functionality. ### Attack Path 1. An attacker, untrusted prompt, or compromised workflow induces the agent to invoke `discord_admin` with the `webhook-list` action. 2. The plugin retrieves the channel or guild webhooks using the privileged Discord bot. 3. The plugin returns each complete `hook.url` in the tool response. 4. The attacker obtains the response through agent output, logs, telemetry, or another consumer of tool results. 5. The attacker extracts the webhook token from the URL. 6. The attacker submits requests directly to the Discord webhook without possessing the bot token. 7. The webhook remains usable until it is deleted or its token is rotated. ### Impact Assessment Exposure grants the ability to authenticate as each disclosed web ...[truncated 353 chars]
- Remediation
- ## Remediation Suggestions - Remove `url` from all `webhook-list` responses. - Return only non-secret metadata such as `id`, `name`, `channelId`, and webhook type. - Treat Discord webhook URLs as credentials in logging and redaction policies. - If URL disclosure is genuinely required, implement a separate operation requiring explicit authorization and confirmation. - Prevent credential-bearing responses from being written to ordinary logs or telemetry. - Rotate or recreate any webhooks whose URLs may already have been exposed through tool history. - Add automated tests asserting that webhook list responses never contain token-bearing URLs.
