Back to skill

Security audit

Feishu Advanced Builder

Security checks for vulnerabilities and agentic risk

Overview

This skill mostly does what it says, but it handles powerful Feishu credentials and remote writes with under-disclosed and unsafe configuration surfaces.

Install only if you are comfortable giving this skill Feishu app credentials with document, board, and Bitable write access. Use a least-privilege Feishu app, avoid setting FEISHU_BASE_URL unless you fully trust and control the endpoint, do not run token-printing commands in logged environments, and test on non-sensitive documents first.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (5)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/feishu-bitable.js:8
Finding
Arbitrary API Base URL Can Exfiltrate Feishu Credentials and Data in Bitable Script<![CDATA[ ## Vulnerability Details **File Location**: `scripts/feishu-bitable.js:8-10, 37-45, 76-82` **Vulnerability Type**: Unrestricted credential destination **Risk Level**: High ### Vulnerable Code ```js const BASE_URL = process.env.FEISHU_BASE_URL || 'https://open.feishu.cn/open-apis'; const APP_ID = process.env.FEISHU_APP_ID; const APP_SECRET = process.env.FEISHU_APP_SECRET; async function feishuFetch(path, { method = 'GET', token, body, retryCount = 0, maxRetries = 5 } = {}) { const headers = { 'Content-Type': 'application/json' }; if (token) headers.Authorization = `Bearer ${token}`; const res = await fetch(`${BASE_URL}${path}`, { method, headers, body: body ? JSON.stringify(body) : undefined, }); } async function getTenantToken() { requiredEnv(); const res = await feishuFetch('/auth/v3/tenant_access_token/internal', { method: 'POST', body: { app_id: APP_ID, app_secret: APP_SECRET }, }); return res.tenant_access_token; } ``` ### Technical Analysis The script permits `FEISHU_BASE_URL` to replace the trusted Feishu API origin without validating the URL scheme or hostname. The application ID and secret are sent to this configurable origin during token acquisition. Subsequent requests also send the resulting bearer token and Bitable content to the same origin. Supporting alternate official deployments can be legitimate, but accepting any process-environment value creates a credential-exfiltration boundary. An attacker who can influence the environment, a launcher, CI configuration, or an agent command can redirect all API traffic to an attacker-controlled server. This behavior is not necessary for the Skill's default Bitable functionality. The official `https://open.feishu.cn/open-apis` endpoint is sufficient unless a strictly validated alternative is explicitly required. ### Attack Path 1. The attacker gains the ability to influence the process environment or execution wrapper. 2. The attacker sets `FEISHU_BASE ...[truncated 1056 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove `FEISHU_BASE_URL` if alternate API origins are not required. - If an override is necessary, parse it with `new URL()` and require `https:`. - Enforce an explicit hostname allowlist, such as `open.feishu.cn`, instead of accepting arbitrary origins. - Reject URLs containing embedded credentials, unexpected ports, fragments, or nonempty paths outside the approved API prefix. - Separate token acquisition from ordinary requests and hard-code its trusted origin. - Avoid forwarding bearer tokens across redirects; preferably disable redirects or verify every redirect destination. - Document any supported private proxy and require an explicit trusted configuration rather than an ambient environment override. - Rotate `FEISHU_APP_SECRET` immediately if the script has been run with an untrusted base URL. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/feishu-board.js:12
Finding
Arbitrary API Base URL Can Exfiltrate Feishu Credentials and Data in Board Script<![CDATA[ ## Vulnerability Details **File Location**: `scripts/feishu-board.js:12-14, 41-49, 66-72` **Vulnerability Type**: Unrestricted credential destination **Risk Level**: High ### Vulnerable Code ```js const BASE_URL = process.env.FEISHU_BASE_URL || 'https://open.feishu.cn/open-apis'; const APP_ID = process.env.FEISHU_APP_ID; const APP_SECRET = process.env.FEISHU_APP_SECRET; async function feishuFetch(path, { method = 'GET', token, body } = {}) { const headers = { 'Content-Type': 'application/json' }; if (token) headers.Authorization = `Bearer ${token}`; const res = await fetch(`${BASE_URL}${path}`, { method, headers, body: body ? JSON.stringify(body) : undefined, }); // Response processing omitted. } async function getTenantToken() { requiredEnv(); const res = await feishuFetch('/auth/v3/tenant_access_token/internal', { method: 'POST', body: { app_id: APP_ID, app_secret: APP_SECRET }, }); return res.tenant_access_token; } ``` ### Technical Analysis `FEISHU_BASE_URL` controls the origin receiving both the application secret and subsequent bearer-authenticated requests. There is no enforcement of HTTPS, no hostname allowlist, and no restriction to a known Feishu API origin. The default traffic to Feishu is necessary for board creation, but allowing arbitrary redirection exceeds the minimum configuration needed for that functionality. Board source, document identifiers, block identifiers, whiteboard tokens, API responses, and authorization tokens can all be exposed to a substituted endpoint. ### Attack Path 1. An attacker modifies the environment used to launch the Skill. 2. `FEISHU_BASE_URL` is set to an attacker-operated server. 3. The user runs `create-whiteboard`, `fill-diagram`, `run`, or `get-tenant-token`. 4. The application ID and secret are posted to the attacker-controlled token endpoint. 5. The attacker returns a fake successful token response. 6. The script sends bearer-authenticated document and bo ...[truncated 553 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Hard-code the trusted Feishu API origin for token acquisition. - Remove the environment override unless it is an essential documented requirement. - If alternate origins must be supported, require HTTPS and validate the exact hostname against a narrow allowlist. - Disable cross-origin redirects or validate the destination before forwarding credentials. - Do not send bearer tokens or secrets to hosts selected solely through ambient environment variables. - Add startup validation that fails closed before reading diagram content or requesting a token. - Rotate the application secret and revoke active tokens after any suspected execution with a manipulated environment. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/feishu-markdown-to-docx.js:13
Finding
Arbitrary API Base URL Can Exfiltrate Feishu Credentials and Document Content in Markdown Converter<![CDATA[ ## Vulnerability Details **File Location**: `scripts/feishu-markdown-to-docx.js:13-15, 42-50, 83-89` **Vulnerability Type**: Unrestricted credential destination **Risk Level**: High ### Vulnerable Code ```js const BASE_URL = process.env.FEISHU_BASE_URL || 'https://open.feishu.cn/open-apis'; const APP_ID = process.env.FEISHU_APP_ID; const APP_SECRET = process.env.FEISHU_APP_SECRET; async function feishuFetch(path, { method = 'GET', token, body, retryCount = 0, maxRetries = 5 } = {}) { const headers = { 'Content-Type': 'application/json' }; if (token) headers.Authorization = `Bearer ${token}`; const res = await fetch(`${BASE_URL}${path}`, { method, headers, body: body ? JSON.stringify(body) : undefined, }); // Response and retry processing omitted. } async function getTenantToken() { requiredEnv(); const res = await feishuFetch('/auth/v3/tenant_access_token/internal', { method: 'POST', body: { app_id: APP_ID, app_secret: APP_SECRET }, }); return res.tenant_access_token; } ``` ### Technical Analysis The converter sends the application ID and secret to a URL selected through the unrestricted `FEISHU_BASE_URL` environment variable. It later sends the tenant bearer token and transformed Markdown content to that same destination. No scheme or origin validation prevents an attacker-controlled host from receiving these values. Retry behavior can also resend the same sensitive request multiple times, although retrying is not the root cause; the unsafe destination selection is. ### Attack Path 1. An attacker influences the shell, CI job, process manager, or agent environment. 2. The attacker sets `FEISHU_BASE_URL` to a server under their control. 3. A user runs the Markdown conversion command with valid Feishu credentials. 4. The application credentials are transmitted to the attacker. 5. A forged successful token response causes processing to continue. 6. Document IDs, parent-block IDs, headings, paragraphs, code ...[truncated 588 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Use a fixed trusted Feishu origin for credential exchange. - If configurability is indispensable, require `https:` and an exact approved hostname. - Reject user-information components, arbitrary ports, redirects to other origins, and malformed URL concatenation. - Keep tenant tokens in memory and bind them to requests for the verified Feishu origin only. - Add automated tests confirming that invalid and attacker-controlled base URLs are rejected before any network request. - Rotate credentials if an untrusted override may have been used. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/feishu-board.js:180
Finding
Tenant Access Token Is Exposed Through Standard Output<![CDATA[ ## Vulnerability Details **File Location**: `scripts/feishu-board.js:180-184` **Vulnerability Type**: Sensitive token disclosure **Risk Level**: Medium ### Vulnerable Code ```js if (cmd === 'get-tenant-token') { const token = await getTenantToken(); print({ ok: true, tenantAccessToken: token }); return; } ``` ### Technical Analysis The `get-tenant-token` command serializes a live Feishu tenant access token to standard output. Standard output is commonly captured by terminal history tooling, CI systems, automation frameworks, agent transcripts, job logs, and observability platforms. The board creation workflow does not require exposing the token to the caller because all other commands acquire and consume the token internally. Returning the credential creates an avoidable disclosure surface. ### Attack Path 1. A user or automation invokes `node scripts/feishu-board.js get-tenant-token`. 2. The script prints the complete tenant access token as JSON. 3. A terminal recorder, CI log collector, agent transcript, or another process captures the output. 4. An attacker with read access to that retained output extracts the token. 5. Before expiration or revocation, the attacker submits authenticated requests to Feishu APIs. ### Impact Assessment The attacker receives the effective application identity represented by the tenant token for its remaining lifetime. The accessible operations are limited by the Feishu application's scopes, but the documented setup includes document and whiteboard read/write capabilities. This may allow unauthorized document or board access and modification. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions - Remove the `get-tenant-token` command unless raw token export is an explicitly required administrative function. - Keep access tokens in process memory and pass them only to verified Feishu API requests. - Return only nonsensitive status information, such as whether authentication succeeded and the token's expiration time. - If token export must remain available, require explicit privileged confirmation and write it only to a protected destination with restrictive permissions rather than stdout. - Redact authorization values from logs, errors, diagnostics, and agent-visible responses. - Revoke exposed tokens and review log-retention systems for historical token disclosure. ]]>

T08 · Insecure Dependencies

Warning
Location
scripts/feishu-markdown-to-docx.js:6
Finding
Markdown Converter Uses an Undeclared and Unpinned Third-Party Dependency<![CDATA[ ## Vulnerability Details **File Location**: `scripts/feishu-markdown-to-docx.js:6-11` **Vulnerability Type**: Unverifiable third-party dependency **Risk Level**: Medium ### Vulnerable Code ```js const { parseMarkdown, generateBlockId, BlockType } = require('feishu-markdown'); ``` ### Technical Analysis The script loads the third-party `feishu-markdown` package, but the audited project contains no `package.json`, version constraint, lockfile, integrity metadata, or vendored implementation. Consequently, users cannot determine which package version was reviewed or reproduce a trusted installation from the artifact alone. There is no evidence in the project that the named package is malicious. The confirmed weakness is the absence of dependency declaration and integrity controls. Because Node modules execute code when loaded, a compromised, substituted, or unexpectedly updated package would execute in the same process as the Skill and could access environment credentials and Markdown data. The imported `BlockType` value is also unused, increasing dependency surface without contributing to functionality. ### Attack Path 1. A user attempts to run the Markdown converter and encounters the missing module. 2. The user or automated setup installs `feishu-markdown` without a project-provided pinned version or lockfile. 3. The package registry resolves a version that differs from the developer's intended or audited version, or the package distribution is compromised. 4. The dependency executes when `require('feishu-markdown')` is evaluated. 5. Malicious dependency code reads `FEISHU_APP_ID`, `FEISHU_APP_SECRET`, local Markdown input, or modifies parsing and network behavior. 6. Sensitive information may be exfiltrated or document output may be manipulated. ### Impact Assessment A compromised dependency executes with the privileges of the Node.js process. It can read process environment variables, access files permitted to the invoking user, alter ...[truncated 194 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Add a `package.json` that declares the exact dependency and supported Node.js version. - Pin an audited package version rather than relying on an unconstrained installation. - Commit a lockfile containing resolved versions and integrity hashes. - Verify the package's publisher, registry origin, repository, maintenance status, and release provenance. - Use automated dependency scanning and update review before changing the locked version. - Consider vendoring or implementing the minimal parsing functionality if the dependency cannot be reliably verified. - Remove the unused `BlockType` import. - Document a reproducible installation command that uses the lockfile, such as `npm ci`, rather than an ad hoc package installation. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (14)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The description claims deep structured Feishu features that are not present in the analyzed implementation, including Mermaid/PlantUML embedding, Bitable API manipulation, and complex lossless Markdown conversion. Such discrepancies make the skill harder to trust and audit, and can conceal the real operational surface from users deciding whether to supply credentials or permit document modifications.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The description claims deep structured Feishu features that are not present in the analyzed implementation, including Mermaid/PlantUML embedding, Bitable API manipulation, and complex lossless Markdown conversion. Such discrepancies make the skill harder to trust and audit, and can conceal the real operational surface from users deciding whether to supply credentials or permit document modifications.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The description claims deep structured Feishu features that are not present in the analyzed implementation, including Mermaid/PlantUML embedding, Bitable API manipulation, and complex lossless Markdown conversion. Such discrepancies make the skill harder to trust and audit, and can conceal the real operational surface from users deciding whether to supply credentials or permit document modifications.

Ae1

High
Category
analysis-evasion
Content
### 1. 🎨 画板图谱注入器 (`scripts/feishu-board.js`)
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
### 3. 📜 高级排版转化引擎 (`scripts/feishu-markdown-to-docx.js`)
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Lp3

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding
The skill advertises and appears to rely on environment variables and networked Feishu API access, but it does not declare any explicit tool scope or permissions boundaries in the skill manifest. That creates an authorization transparency gap: operators and downstream agents cannot easily tell what capabilities the skill needs, increasing the chance of over-broad execution or accidental secret/data exposure.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The skill emphasizes broad write access to documents, boards, and tables without clearly warning that it can modify user data and structured content. In a skill whose purpose is direct mutation of collaborative assets, the absence of a modification warning increases the chance of unintended writes, destructive updates, or misuse with overly privileged accounts.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The skill instructs users to provide Feishu app credentials but does not include an explicit warning about sensitive secret handling, storage, rotation, or least-privilege configuration. That increases the risk of users pasting high-value credentials into insecure contexts or granting an app broader access than necessary.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
The document is written as an agent-facing reference entirely in Chinese, including the title and operational guidance, without indicating that language choice is optional or that the skill is intended only for a Chinese-speaking or region-specific context. This can violate language/locale policy because it implicitly constrains skill operation to a specific language without user opt-in.

Description-Behavior Mismatch

Medium
Confidence
94% confidence
Finding
The header documentation says "Create spreadsheets with any size", but createBitable explicitly limits processing to Math.min(rowCount, 100) at L139. Additionally, writeBatch converts individual cell coordinates into append-record calls without using row indices, so the behavior is not faithful to arbitrary spreadsheet creation and is materially narrower than the claim.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The script prints the freshly obtained tenant access token directly to stdout in the `get-tenant-token` command. In CLI and agent environments, stdout is commonly captured by logs, orchestration frameworks, chat transcripts, or other tools, so this can leak a credential that enables authenticated Feishu API access.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The script reads an arbitrary local Markdown file and uploads its full contents to the Feishu document API with no explicit confirmation, dry-run mode, or visibility warning at the point of exfiltration. In an agent-skill context, this creates a real data-exposure risk because a caller may pass sensitive local files or be unaware that all content is being transmitted to a remote SaaS endpoint.

Natural-Language Policy Violations

Low
Confidence
81% confidence
Finding
The natural-language comments present the description under a Chinese-only heading ("中文说明") with no corresponding language choice or alternate locale. This can violate language/locale policy when a skill assumes a specific language without user opt-in or justification.

Missing User Warnings

Low
Confidence
84% confidence
Finding
The create-whiteboard, fill-diagram, and run commands perform write operations against Feishu APIs that modify documents and whiteboards. Although these actions are the script's purpose, the CLI provides no explicit user-facing warning that running these commands will alter remote content, which can matter for accidental invocation or use in automation.

Static analysis

Detected: suspicious.env_credential_access

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/feishu-bitable.js:8

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/feishu-board.js:12

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/feishu-markdown-to-docx.js:13