T09 · Insecure Skill Coding Practices
Error
- Location
- assets/discord-backend.ts:400
- Finding
- Discord Bot Token Is Stored in an Inconsistent Plaintext Configuration Field<![CDATA[ ## Vulnerability Details **File Location**: `assets/discord-backend.ts`, lines 98–100 and 400–412 **Vulnerability Type**: Plaintext credential storage and inconsistent configuration key **Risk Level**: High ### Complete Code Snippet ```ts /** * Get the current Discord bot token from config. */ function getToken(ctx: ServerMethodContext): string | undefined { const config = ctx.serverState.config; return config.channels?.discord?.botToken; } ``` ```ts // Merge in the new token const updatedConfig = { ...snapshot.config, channels: { ...snapshot.config.channels, discord: { ...snapshot.config.channels?.discord, token: params.token, }, }, }; // Write the updated config await writeConfigFile(updatedConfig); ``` ### Technical Analysis The token retrieval and token storage paths use different configuration keys. `getToken()` reads `channels.discord.botToken`, while `discordSetToken()` writes the supplied secret to `channels.discord.token`. This inconsistency can prevent the newly submitted token from being activated while still retaining the raw credential in the configuration file. It may also result in duplicate or abandoned secret fields that are not covered by normal credential-management procedures. The implementation directly passes the submitted token to the ordinary configuration writer. It does not convert the token into an OpenBao reference or invoke a secret-storage API, despite the documentation presenting OpenBao-backed credential storage as a security feature. The backend also does not resolve an OpenBao reference before using the value as a Discord authorization credential. The vulnerability is not an indication that the token is sent to an unauthorized domain. Token validation requests are limited to the official Discord HTTPS API. The issue concerns local storage, lifecycle management, and the discrepancy between the claimed and implemented secret-handling behavior. ### Attack Path 1. An authoriz ...[truncated 1150 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Store and retrieve the credential using one canonical key, preferably `channels.discord.botToken`. 2. Add a migration that securely removes any legacy `channels.discord.token` value after moving it to the canonical storage location. 3. Integrate with the host secret-management API rather than writing raw bot tokens through the ordinary configuration writer. 4. When OpenBao references are supported, resolve them through the trusted secret provider immediately before API use and never persist the resolved value. 5. Ensure configuration and backup files containing credentials are created with owner-only permissions. 6. Redact both `token` and `botToken` fields from logs, support bundles, configuration exports, and error reports. 7. Add automated tests confirming that token submission, storage, retrieval, restart, and secret-reference resolution all use the same configuration contract. ]]>
