T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/plan-a-demo.js:8
- Finding
- Hardcoded production identifiers can route employee data to an unintended Discord channel<![CDATA[ ## Vulnerability Details **File Location**: `scripts/plan-a-demo.js:8-13`, `scripts/plan-a-demo.js:123-124`, `scripts/plan-a-demo.js:216-217`, `scripts/plan-a-demo.js:240-249` **Vulnerability Type**: Hardcoded production routing identifiers and unsafe default configuration **Risk Level**: High ### Vulnerable Code ```js const CONFIG = { spreadsheetId: process.env.PLAN_A_SHEET_ID || '17JU1m6rBOhlD7vqSTrMOSPcEQehO04HnYg7oMeDXnn8', staffTab: process.env.PLAN_A_STAFF_TAB || 'Trang tính1', eventsTab: process.env.PLAN_A_EVENTS_TAB || 'NgayDacBiet', discordChannelId: process.env.DISCORD_CHANNEL_ID || '1483444824895000697', discordBotToken: process.env.DISCORD_BOT_TOKEN || '', remindDaysDefault: Number(process.env.PLAN_A_REMIND_DAYS || 3), runDate: process.env.PLAN_A_RUN_DATE || '', gogAccount: process.env.GOG_ACCOUNT || 'vinhtamforwork@gmail.com', ``` The report includes employee names and departments: ```js for (const item of data.birthdaysToday) lines.push(`- 🎂 Sinh nhật: ${item.name} (${item.dept || 'Chưa rõ bộ phận'})`); for (const item of data.eventsToday) lines.push(`- 🎉 Sự kiện: ${item.name}${item.owner ? ` — phụ trách ${item.owner}` : ''}`); ``` The resulting report is transmitted to the configured or default Discord channel: ```js async function sendDiscordMessage(content) { if (!CONFIG.discordBotToken) throw new Error('Thiếu DISCORD_BOT_TOKEN'); const res = await fetch(`https://discord.com/api/v10/channels/${CONFIG.discordChannelId}/messages`, { method: 'POST', headers: { Authorization: `Bot ${CONFIG.discordBotToken}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ content }), }); ``` ### Technical Analysis Sending reminder reports to Discord is part of the declared functionality, and the script uses Discord's official HTTPS API. The security problem is that the spreadsheet ID, Google account, and Discord channel ID use real-looking hardcoded defaults rather than mandatory de ...[truncated 1802 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Remove all real spreadsheet, account, and channel identifiers from the source code. 2. Require `PLAN_A_SHEET_ID`, `GOG_ACCOUNT`, and `DISCORD_CHANNEL_ID` to be explicitly configured. 3. Validate required configuration before reading data or sending a message, and terminate safely if any value is missing. 4. For manual sends, display the destination channel and require explicit confirmation unless a noninteractive production flag is intentionally supplied. 5. Use clearly invalid placeholders in examples rather than operational identifiers. 6. Restrict the Discord bot to only the intended server and channel, with message-send permission only. 7. Minimize report contents to information necessary for the reminder workflow and establish organizational approval for processing employee birthday data. 8. Keep invalid-record details disabled by default and avoid posting employee codes or raw malformed values into group chats. 9. Add deployment tests that verify there are no fallback production destinations. ]]>
