T05 · Unauthorized Access and Privilege Escalation
- Location
scripts/test-feishu-chat.js:3- Finding
Undeclared Feishu Tenant Chat Enumeration Exceeds Least Privilege
- Content
View full analysis
Vulnerability Details
File Location:
scripts/test-feishu-chat.js, lines 3–45
Vulnerability Type: Excessive privilege use and tenant metadata enumeration
Risk Level: MediumVulnerable Code
js async function getChatList() { const token = await new Promise((resolve, reject) => { const data = JSON.stringify({ app_id: process.env.FEISHU_APP_ID, app_secret: process.env.FEISHU_APP_SECRET }); const req = https.request({ hostname: 'open.feishu.cn', port: 443, path: '/open-apis/auth/v3/tenant_access_token/internal', method: 'POST', headers: { 'Content-Type': 'application/json', 'Content-Length': data.length } }, res => { let body = ''; res.on('data', chunk => body += chunk); res.on('end', () => resolve(JSON.parse(body).tenant_access_token)); }); req.on('error', reject); req.write(data); req.end(); }); console.log('✅ Token obtained successfully'); // Retrieve the chat list const req = https.request({ hostname: 'open.feishu.cn', port: 443, path: '/open-apis/im/v1/chats?page_size=10', method: 'GET', headers: { 'Authorization': 'Bearer ' + token, 'Content-Type': 'application/json' } }, res => { let body = ''; res.on('data', chunk => body += chunk); res.on('end', () => { const result = JSON.parse(body); if (result.code === 0) { console.log('\n📋 Available chat list:'); result.data.items.forEach((chat, i) => { console.log(`${i + 1}. ${chat.name} (ID: ${chat.chat_id})`); });Technical Analysis
The script reads
FEISHU_APP_IDandFEISHU_APP_SECRET, submits them to Feishu's official authentication endpoint, obtains a tenant access token, and uses that token to enumerate chats accessible to the application. It then prints chat names a ...[truncated 2142 chars]- Remediation
View remediation
Remediation Suggestions
- Remove
scripts/test-feishu-chat.jsfrom the distributed Skill if chat discovery is not part of its supported functionality. - If retained as an administrative utility, clearly document that it is optional, separate it from normal Skill execution, and require explicit operator confirmation before requesting a tenant token.
- Add
FEISHU_APP_IDandFEISHU_APP_SECRETto documentation only if this administrative feature is intentionally supported; do not imply that they are needed for webhook-based report delivery. - Use a dedicated Feishu application with only the minimum read scope required for chat discovery. Do not reuse a broadly privileged production application.
- Avoid printing raw chat IDs by default. Redact identifiers and reveal them only through an explicit option intended for interactive administration.
- Warn operators that output may enter CI systems or retained terminal logs, and disable this utility in automated execution environments.
- Validate HTTP status codes and Feishu response codes before accepting
tenant_access_token; handle missing or malformed tokens without proceeding. - Keep the token in memory only, never log it, and discard it immediately after the request completes.
- Prefer webhook-only delivery for the normal Skill path because it avoids tenant-wide credentials and chat-enumeration permissions.
- Remove
