T09 · Insecure Skill Coding Practices
- Location
scripts/index.js:17- Finding
Attacker-Controlled API Domain Can Receive Feishu Application Credentials
- Content
View full analysis
Vulnerability Details
File Location:
scripts/index.js, lines 17–23, 29–35, and 47–52
Vulnerability Type: Unvalidated authentication endpoint configuration
Risk Level: HighVulnerable Code
js function createAuthClient() { return new lark.Client({ appId: process.env.FEISHU_APP_ID, appSecret: process.env.FEISHU_APP_SECRET, appType: lark.AppType.SelfBuild, domain: process.env.FEISHU_DOMAIN || 'https://open.feishu.cn', disableTokenCache: true, }); }js function createApiClient() { return new lark.Client({ appId: process.env.FEISHU_APP_ID, appSecret: process.env.FEISHU_APP_SECRET, appType: lark.AppType.SelfBuild, domain: process.env.FEISHU_DOMAIN || 'https://open.feishu.cn', disableTokenCache: true, }); }js const response = await authClient.auth.v3.tenantAccessToken.internal({ data: { app_id: process.env.FEISHU_APP_ID, app_secret: process.env.FEISHU_APP_SECRET, }, }, lark.withTenantToken(''));Technical Analysis
The CLI accepts
FEISHU_DOMAINdirectly from the environment and uses it as the Lark SDK base domain without validating its scheme, host, port, or origin. The authentication flow subsequently sendsFEISHU_APP_IDandFEISHU_APP_SECRETthrough the client configured with that domain.An attacker who can supply or modify the process environment or project
.envfile can setFEISHU_DOMAINto an attacker-controlled endpoint. When a user runs any command that callswithToken(), the CLI invokesgetTenantToken()and may transmit the application credentials to that endpoint.The same unvalidated domain is also used for subsequent API operations. This could expose uploaded local files, document content, document tokens, folder tokens, and tenant access tokens to the configured server.
Attack Path
- The attacker gains the ability to provide or modify the project's
.envfile or execution environment. - The attacker sets
FEISHU_DOMAINt ...[truncated 1728 chars]
- The attacker gains the ability to provide or modify the project's
- Remediation
View remediation
Remediation Suggestions
- Remove support for an arbitrary
FEISHU_DOMAINif custom API endpoints are not required. Use a fixed official Feishu endpoint:
js const FEISHU_API_ORIGIN = 'https://open.feishu.cn';- If both Feishu and Lark deployments must be supported, use an explicit allowlist of complete trusted origins rather than accepting arbitrary URLs:
js const ALLOWED_ORIGINS = new Set([ 'https://open.feishu.cn', 'https://open.larksuite.com', ]); function getValidatedDomain() { const configured = process.env.FEISHU_DOMAIN || 'https://open.feishu.cn'; const parsed = new URL(configured); if ( parsed.protocol !== 'https:' || parsed.username || parsed.password || parsed.pathname !== '/' || parsed.search || parsed.hash || !ALLOWED_ORIGINS.has(parsed.origin) ) { throw new Error('FEISHU_DOMAIN must be an approved official API origin'); } return parsed.origin; }-
Use the validated origin in both
createAuthClient()andcreateApiClient(). -
Reject HTTP endpoints, embedded credentials, unexpected ports, subdomain suffix tricks, redirects to untrusted origins, and URLs containing paths, query strings, or fragments.
-
Do not enable arbitrary custom domains through project-local
.envfiles. If custom enterprise gateways are essential, configure trusted endpoints through an administrator-controlled mechanism and pin their expected TLS identity. -
Ensure authentication requests do not follow cross-origin redirects. Verify SDK redirect behavior and disable redirects or validate every redirect target before forwarding credentials.
-
Treat any credentials used while an untrusted domain was configured as compromised. Rotate
FEISHU_APP_SECRET, revoke active tenant tokens where supported, review application activity, and audit affected documents and drive resources. -
Apply least privilege to the Feishu application so credential compromise does not automatically grant read, write, upload, i ...[truncated 54 chars]
- Remove support for an arbitrary
