Back to skill

Security audit

Feishu Docs

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its Feishu document-management purpose, but its configurable API domain can expose Feishu app credentials and document data to an unintended server.

Install only if you trust the publisher and can control the .env/runtime environment. Keep FEISHU_DOMAIN fixed to the official Feishu/Lark API origin, use a least-privilege Feishu app, treat overwrite updates and delete commands as destructive, and avoid importing sensitive local files unless you intend to upload them to Feishu.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Error
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: High

Vulnerable 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_DOMAIN directly from the environment and uses it as the Lark SDK base domain without validating its scheme, host, port, or origin. The authentication flow subsequently sends FEISHU_APP_ID and FEISHU_APP_SECRET through the client configured with that domain.

An attacker who can supply or modify the process environment or project .env file can set FEISHU_DOMAIN to an attacker-controlled endpoint. When a user runs any command that calls withToken(), the CLI invokes getTenantToken() 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

  1. The attacker gains the ability to provide or modify the project's .env file or execution environment.
  2. The attacker sets FEISHU_DOMAIN t ...[truncated 1728 chars]
Remediation
View remediation

Remediation Suggestions

  1. Remove support for an arbitrary FEISHU_DOMAIN if custom API endpoints are not required. Use a fixed official Feishu endpoint:
js
const FEISHU_API_ORIGIN = 'https://open.feishu.cn';
  1. 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;
}
  1. Use the validated origin in both createAuthClient() and createApiClient().

  2. Reject HTTP endpoints, embedded credentials, unexpected ports, subdomain suffix tricks, redirects to untrusted origins, and URLs containing paths, query strings, or fragments.

  3. Do not enable arbitrary custom domains through project-local .env files. If custom enterprise gateways are essential, configure trusted endpoints through an administrator-controlled mechanism and pin their expected TLS identity.

  4. Ensure authentication requests do not follow cross-origin redirects. Verify SDK redirect behavior and disable redirects or validate every redirect target before forwarding credentials.

  5. 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.

  6. Apply least privilege to the Feishu application so credential compromise does not automatically grant read, write, upload, i ...[truncated 54 chars]

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (27)

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · README.md (reported line 11)May include surrounding context.

md
本项目使用飞书开放平台的**自建应用**模式进行认证:

1. **Tenant Access Token**: 通过 `app_id` 和 `app_secret` 获取租户访问令牌
   - 令牌有效期为 2 小时
   - 内置缓存机制,提前 5 分钟刷新,避免频繁请求

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/index.js (reported line 37)May include surrounding context.

js
本项目使用飞书开放平台的**自建应用**模式进行认证:

1. **Tenant Access Token**: 通过 `app_id` 和 `app_secret` 获取租户访问令牌
   - 令牌有效期为 2 小时
   - 内置缓存机制,提前 5 分钟刷新,避免频繁请求

Tp4

High
Category
MCP Tool Poisoning
Confidence
91% confidence
Finding

The declared description narrows the skill to Feishu document management, but the documented behavior extends into broader Drive operations, structured block extraction, and importing into additional target types. This mismatch can mislead users about the real authority and data-handling surface of the skill, which is dangerous in a security-sensitive agent context because users may grant trust or provide inputs under false assumptions.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 60)May include surrounding context.

md
node scripts/index.js get -d doccxxxxxxxxxxxxxx

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 63)May include surrounding context.

md
node scripts/index.js get -d doccxxxxxxxxxxxxxx

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 66)May include surrounding context.

md
node scripts/index.js get -d doccxxxxxxxxxxxxxx

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 73)May include surrounding context.

md
node scripts/index.js get -d doccxxxxxxxxxxxxxx

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 76)May include surrounding context.

md
node scripts/index.js get -d doccxxxxxxxxxxxxxx

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 83)May include surrounding context.

md
node scripts/index.js get -d doccxxxxxxxxxxxxxx

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 86)May include surrounding context.

md
node scripts/index.js get -d doccxxxxxxxxxxxxxx

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 93)May include surrounding context.

md
node scripts/index.js get -d doccxxxxxxxxxxxxxx

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 96)May include surrounding context.

md
node scripts/index.js get -d doccxxxxxxxxxxxxxx

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 103)May include surrounding context.

md
node scripts/index.js get -d doccxxxxxxxxxxxxxx

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 106)May include surrounding context.

md
node scripts/index.js get -d doccxxxxxxxxxxxxxx

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 113)May include surrounding context.

md
node scripts/index.js get -d doccxxxxxxxxxxxxxx

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/index.js (reported line 89)May include surrounding context.

js
const missing = required.filter(key => !process.env[key]);
  if (missing.length > 0) {
    console.error('❌ 缺少必要的环境变量:', missing.join(', '));
    console.log('\n请创建 .env 文件并配置以下变量:');
    console.log('FEISHU_APP_ID=你的应用ID');
    console.log('FEISHU_APP_SECRET=你的应用密钥');
    process.exit(1);

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/index.js (reported line 582)May include surrounding context.

js
const missing = required.filter(key => !process.env[key]);
  if (missing.length > 0) {
    console.error('❌ 缺少必要的环境变量:', missing.join(', '));
    console.log('\n请创建 .env 文件并配置以下变量:');
    console.log('FEISHU_APP_ID=你的应用ID');
    console.log('FEISHU_APP_SECRET=你的应用密钥');
    process.exit(1);

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The README documents an update mode that deletes all existing blocks before writing new content, but the warning is easy to miss and does not clearly emphasize irreversible data loss, backup considerations, or safer alternatives. In a document-management skill, this is operationally dangerous because users may run the command expecting an in-place edit and accidentally destroy document content.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill declares required environment variables and invokes external code capabilities, but it does not define an explicit tool scope such as permissions or allowed-tools. That makes the skill's operational authority less transparent to users and reviewers, increasing the chance of overbroad execution or unintended access to secrets during use.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
85% confidence
Finding

The create command can read local content or accept inline content and then sends that content to Feishu via document conversion and creation APIs. Similarly, the update command sends provided content to remote APIs, but there is no clear user-facing warning in the command descriptions or help text that document data will leave the local system.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The import-file command reads a local file and uploads its contents to the Feishu API, which transmits user data over the network. While progress logs are shown, the command description and options do not clearly warn users that local file contents will be sent to a remote service.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The skill documentation is entirely written in Chinese and does not indicate that language choice is optional or that the skill is intended only for Chinese-speaking users. This can violate language or locale policy when users are not given an explicit language opt-in or justified regional scope.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The skill notes that document metadata is saved to a local JSON file as a side effect, but this is not clearly surfaced where users are most likely to act on create commands. Undisclosed local writes can expose document identifiers or metadata, cause workspace pollution, and create unexpected persistence that may later be consumed by other tools or agents.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The description string is entirely in Chinese ("飞书文档管理命令行工具"), which signals a language-specific skill without any indication of user choice or documented locale constraint. Under the policy, language restrictions should either offer opt-in/choice or be clearly justified as region-specific.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
92% confidence
Finding

Using a caret version range for @larksuiteoapi/node-sdk allows automatically resolving to newer minor or patch releases, which can introduce unexpected or compromised upstream code through the supply chain. In a tool that manages cloud documents and likely handles access tokens, dependency drift increases the risk of importing vulnerable or malicious code into a privileged context.

Content

Scanner excerpt · package.json (reported line 14)May include surrounding context.

json
},
  "private": true,
  "dependencies": {
    "@larksuiteoapi/node-sdk": "^1.58.0",
    "commander": "^14.0.3",
    "dotenv": "^17.2.4"
  }

Static analysis

No suspicious patterns detected.