Back to skill

Security audit

Feishu Skills Kit 飞书技能全集

Security checks for vulnerabilities and agentic risk

Overview

This is a real Feishu integration bundle, but it needs Review because it combines Feishu credentials, persistent bridge execution, broad local-agent access, and exploitable command-handling flaws.

Install only after reviewing the external MCP server repository at a pinned commit, replacing shell-string execution in the card scripts, using least-privilege Feishu app scopes, configuring explicit allowed Feishu senders/chats for the bridge, and deciding whether a persistent LaunchAgent is acceptable. Treat any configured Feishu App Secret and local gateway token as high-value credentials.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • System PersistenceInstalls backdoors, hooks, services, or scheduled tasks that survive the run
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
Findings (8)

T03 · Remote Payload Retrieval and Execution

Error
Location
README.md:165
Finding
Unpinned Remote Repository Is Downloaded and Executed with Feishu Credentials<![CDATA[ ## Vulnerability Details **File Location**: `README.md:165-171`; related persistent execution configuration in `mcp-config-template.json:3-12` **Vulnerability Type**: Unpinned remote payload retrieval and execution **Risk Level**: Critical ### Vulnerable Code ```bash # Clone MCP Server cd ~/.openclaw/workspace/skills 2>/dev/null || mkdir -p ~/.openclaw/workspace/skills && cd ~/.openclaw/workspace/skills git clone https://github.com/Shuai-DaiDai/feishu-doc-manager.git cd feishu-doc-manager # Execute install.sh if it exists [ -f install.sh ] && bash install.sh ``` The resulting external script is then configured as an MCP process with Feishu credentials: ```json "feishu-doc-manager": { "command": "bash", "args": [ "<FEISHU_DOC_MANAGER_INSTALL_PATH>/install.sh" ], "env": { "FEISHU_APP_ID": "<YOUR_FEISHU_APP_ID>", "FEISHU_APP_SECRET": "<YOUR_FEISHU_APP_SECRET>" }, "_comment": "Feishu document management MCP Server" } ``` ### Technical Analysis The installation procedure clones the current default branch of an external GitHub repository without selecting an immutable commit, release artifact, checksum, or cryptographic signature. It then immediately executes `install.sh`. The executed script is not included in this project, so its effective behavior can change after this project has been reviewed. In addition, the MCP template repeatedly executes that external script while exposing `FEISHU_APP_ID` and `FEISHU_APP_SECRET` through its environment. This creates a time-of-review versus time-of-use supply-chain boundary: the code ultimately executed by the user is not fixed by this repository. ### Attack Path 1. An attacker compromises the external repository, its maintainer account, or its default branch. 2. The attacker modifies `install.sh` or files loaded by that script. 3. A user follows the documented installation process and clones the modified default branch. 4. The user runs `bash install.sh`, causing attacker-controlle ...[truncated 759 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Vendor the reviewed MCP implementation into the audited distribution where feasible. 2. Otherwise, pin the clone to a reviewed immutable commit: ```bash git clone https://github.com/Shuai-DaiDai/feishu-doc-manager.git cd feishu-doc-manager git checkout --detach <REVIEWED_COMMIT_SHA> ``` 3. Verify the checked-out commit and published artifact using a trusted signature or checksum before execution. 4. Do not use `install.sh` itself as the long-running MCP entry point. Configure a fixed, reviewed executable after installation. 5. Do not automatically execute newly downloaded shell scripts. 6. Run the external component in a sandbox with only required filesystem and network access. 7. Supply a separate least-privileged Feishu application credential rather than credentials shared with unrelated skills. 8. Document the exact reviewed upstream revision and establish a controlled update-review process. ]]>

T06 · System Persistence

Error
Location
skills/feishu-bridge/setup-service.mjs:29
Finding
Persistent macOS Launch Agent Keeps the Credential-Bearing Bridge Running<![CDATA[ ## Vulnerability Details **File Location**: `skills/feishu-bridge/setup-service.mjs:29-75` **Vulnerability Type**: Cross-session service persistence **Risk Level**: High ### Vulnerable Code ```js const plist = `<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>${LABEL}</string> <key>ProgramArguments</key> <array> <string>${NODE_PATH}</string> <string>${BRIDGE_PATH}</string> </array> <key>WorkingDirectory</key> <string>${WORK_DIR}</string> <key>RunAtLoad</key> <true/> <key>KeepAlive</key> <true/> <key>EnvironmentVariables</key> <dict> <key>HOME</key> <string>${HOME}</string> <key>PATH</key> <string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string> <key>FEISHU_APP_ID</key> <string>${APP_ID}</string> <key>FEISHU_APP_SECRET_PATH</key> <string>${SECRET_PATH}</string> </dict> <key>StandardOutPath</key> <string>${HOME}/.clawdbot/logs/feishu-bridge.out.log</string> <key>StandardErrorPath</key> <string>${HOME}/.clawdbot/logs/feishu-bridge.err.log</string> </dict> </plist> `; // Ensure logs dir fs.mkdirSync(`${HOME}/.clawdbot/logs`, { recursive: true }); const outPath = path.join(HOME, 'Library', 'LaunchAgents', `${LABEL}.plist`); fs.mkdirSync(path.dirname(outPath), { recursive: true }); fs.writeFileSync(outPath, plist); ``` ### Technical Analysis The setup program creates a LaunchAgent under the user's `~/Library/LaunchAgents` directory. `RunAtLoad` causes the bridge to start when the agent is loaded, including subsequent login sessions, and `KeepAlive` instructs launchd to restart it after termination. An always-running service is relevant to a real-time Feishu bridge, and the repository documents the behavior. Nevertheless, it crosses the privilege ...[truncated 1463 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Make foreground execution the default and persistence an explicit, separately confirmed option. 2. Display a clear warning that setup creates a login-persistent, automatically restarted process with access to Feishu and gateway credentials. 3. Generate the property list only after interactive confirmation. 4. XML-escape every interpolated value or use a structured property-list library. 5. Write the property list with restrictive permissions and verify ownership. 6. Add a supported removal command that unloads the service and deletes the property list: ```bash launchctl unload ~/Library/LaunchAgents/com.clawdbot.feishu-bridge.plist rm ~/Library/LaunchAgents/com.clawdbot.feishu-bridge.plist ``` 7. Minimize the bridge's gateway scopes and Feishu application permissions. 8. Pin and lock all bridge dependencies before deploying it as a persistent service. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
skills/feishu-card/handle_event.js:7
Finding
Shell Command Injection Through Untrusted Feishu Event Fields<![CDATA[ ## Vulnerability Details **File Location**: `skills/feishu-card/handle_event.js:7-20` **Vulnerability Type**: OS command injection **Risk Level**: Critical ### Vulnerable Code ```js if (eventPayload.header.event_type === 'application.bot.menu_v6') { const userOpenId = eventPayload.sender.sender_id.open_id; const menuKey = eventPayload.event.event_key; console.log(`User ${userOpenId} clicked menu: ${menuKey}`); // Response logic // We can call send.js here const { execSync } = require('child_process'); try { const replyText = `收到!你点击了菜单按钮:\`${menuKey}\` 喵!😺`; execSync(`node ${__dirname}/send.js --target "${userOpenId}" --text "${replyText}" --color "green"`); } catch (e) { console.error("Failed to send reply:", e); } } ``` ### Technical Analysis Both `userOpenId` and `menuKey` originate from the event payload and are interpolated into a command string passed to `execSync`. Node.js executes a string supplied to `execSync` through a shell. Wrapping attacker-controlled values in double quotes is not sufficient. Shell command substitution using constructs such as `$(command)` or backticks remains active inside double-quoted strings. Embedded quotes can also terminate the intended argument and introduce shell operators. No schema validation, identifier allowlist, menu-key allowlist, or shell-neutral argument API is used before execution. ### Attack Path 1. An attacker causes the handler to receive an event payload with a crafted `sender.sender_id.open_id` or `event.event_key`. 2. The malicious value contains shell syntax, such as command substitution or a quote followed by a command separator. 3. The handler constructs a single shell command containing the malicious value. 4. `execSync` invokes the shell. 5. The shell evaluates the injected syntax before or while launching `send.js`. 6. The injected command runs with the privileges and environment of the event-handler process. ## ...[truncated 393 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Replace shell-string execution with a shell-free argument array: ```js const path = require('path'); const { execFileSync } = require('child_process'); const sender = path.resolve(__dirname, 'send.js'); execFileSync(process.execPath, [ sender, '--target', userOpenId, '--text', replyText, '--color', 'green' ], { stdio: 'inherit', shell: false }); ``` Additionally: 1. Validate `open_id` against the expected Feishu identifier format. 2. Restrict `menuKey` to a predefined allowlist of configured menu actions. 3. Validate the complete event schema before dereferencing fields. 4. Verify event authenticity before processing events in a real webhook deployment. 5. Run the event handler with a minimal environment and no unnecessary filesystem permissions. 6. Add tests containing quotes, backticks, `$()`, semicolons, newlines, and shell metacharacters. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
skills/feishu-card/send_safe.js:30
Finding
The “Safe” Card Sender Is Still Vulnerable to Shell Command Injection<![CDATA[ ## Vulnerability Details **File Location**: `skills/feishu-card/send_safe.js:30-42` **Vulnerability Type**: OS command injection in a security wrapper **Risk Level**: High ### Vulnerable Code ```js // 2. Construct command for the real sender // Note: We use the absolute path to send.js const senderScript = path.resolve(__dirname, 'send.js'); // Build arguments array for spawn/exec // We construct the command string carefully. // Since we are invoking via execSync, we still need to quote arguments, // BUT the dangerous content is now inside a file, so we only quote the filename. let cmd = `node "${senderScript}" --target "${options.target}" --text-file "${tempFile}" --color "${options.color}"`; if (options.title) cmd += ` --title "${options.title}"`; console.log(`[SafeSend] Executing: ${cmd}`); execSync(cmd, { stdio: 'inherit' }); ``` ### Technical Analysis The wrapper safely writes only `options.text` to a temporary file. It still places `options.target`, `options.color`, and the optional `options.title` directly into a shell command string. These values are CLI inputs and are not validated. Double quotes do not neutralize shell command substitution, and injected quotes can terminate the surrounding argument. The filename is generated internally, but securing it does not protect the remaining attacker-controlled fields. The filename `send_safe.js` and its comments may lead callers to incorrectly assume that all inputs are shell-safe. ### Attack Path 1. An attacker or an upstream agent controls `--target`, `--color`, or `--title`. 2. The attacker includes shell metacharacters or command-substitution syntax in the selected argument. 3. `send_safe.js` concatenates the value into `cmd`. 4. `execSync` sends the command string to a shell. 5. The shell executes the injected command with the privileges of the skill process. ### Impact Assessment Successful exploitation gives arbitrary local command execution. The process may expose Feishu credenti ...[truncated 229 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Use `spawnSync` or `execFileSync` with an argument array and no shell: ```js const { spawnSync } = require('child_process'); const args = [ senderScript, '--target', options.target, '--text-file', tempFile, '--color', options.color ]; if (options.title) { args.push('--title', options.title); } const result = spawnSync(process.execPath, args, { stdio: 'inherit', shell: false }); if (result.error) throw result.error; if (result.status !== 0) process.exit(result.status); ``` Also: 1. Validate target identifiers against documented Feishu ID or email formats. 2. Restrict colors to an explicit allowlist. 3. Set maximum lengths for titles and other metadata. 4. Create temporary files in an operating-system temporary directory with restrictive permissions. 5. Add regression tests for shell metacharacters in every CLI option. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
skills/feishu-card/send.js:82
Finding
Secret-Detection Failure Falls Back to Sending the Rejected Secret<![CDATA[ ## Vulnerability Details **File Location**: `skills/feishu-card/send.js:82-96, 125, 198-210` **Vulnerability Type**: Security-control bypass and sensitive-data disclosure **Risk Level**: High ### Vulnerable Code The sender intentionally rejects content matching selected secret formats: ```js function scanForSecrets(content) { if (!content) return; const secretPatterns = [ /sk-ant-api03-[a-zA-Z0-9\-_]{20,}/, /ghp_[a-zA-Z0-9]{10,}/, /xox[baprs]-[a-zA-Z0-9]{10,}/, /-----BEGIN [A-Z]+ PRIVATE KEY-----/ ]; for (const p of secretPatterns) { if (p.test(content)) { console.error('\x1b[31m%s\x1b[0m', '⛔ SECURITY ALERT: Potential secret detected in message body.'); throw new Error('Aborted send to prevent secret leakage.'); } } } ``` The check is called before the interactive-card send: ```js scanForSecrets(contentText); ``` However, the same exception is caught by the generic delivery fallback: ```js } catch (e) { console.error('Error during Card Send:', e.message); console.log('[Feishu-Card] Attempting fallback to plain text...'); // Fallback Logic let contentText = options.text || ''; if (options.textFile) try { contentText = fs.readFileSync(options.textFile, 'utf8'); } catch(e){} let receiveIdType = 'open_id'; if (options.target.startsWith('oc_')) receiveIdType = 'chat_id'; try { await sendPlainTextFallback(receiveIdType, options.target, contentText, options.title); } catch (fallbackError) { console.error('Fallback failed dramatically:', fallbackError.message); process.exit(1); } } ``` ### Technical Analysis `scanForSecrets` throws an ordinary `Error`. The outer `catch` does not distinguish a security-policy rejection from an API or card-format failure. It consequently reloads the original message and passes it to `sendPlainTextFallback`, which performs no secret scan before transmissi ...[truncated 1285 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Define a dedicated error type for security-policy rejection: ```js class SecretDetectedError extends Error {} ``` 2. Rethrow or terminate immediately when that error is caught; never enter delivery fallback. 3. Scan the final serialized content immediately before every outbound transmission, including fallback messages. 4. Separate content-validation errors from transport, API, and rendering errors. 5. Expand detection to configurable organization-specific patterns, but do not treat pattern matching as the only control. 6. Add explicit user confirmation and redaction for content that resembles credentials. 7. Add a regression test proving that a detected secret produces zero network calls. 8. Avoid logging the rejected content or sensitive response details. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
skills/feishu-bridge/bridge.mjs:103
Finding
Untrusted Feishu Messages Are Forwarded to an Operator-Scoped Local Agent<![CDATA[ ## Vulnerability Details **File Location**: `skills/feishu-bridge/bridge.mjs:103-126, 171-202` **Vulnerability Type**: Missing authorization and excessive gateway privileges **Risk Level**: High ### Vulnerable Code The bridge authenticates to the local gateway with broad operator permissions: ```js if (msg.type === 'event' && msg.event === 'connect.challenge') { ws.send(JSON.stringify({ type: 'req', id: 'connect', method: 'connect', params: { minProtocol: 3, maxProtocol: 3, client: { id: 'gateway-client', version: '0.2.0', platform: 'macos', mode: 'backend' }, role: 'operator', scopes: ['operator.read', 'operator.write'], auth: { token: GATEWAY_TOKEN }, locale: 'zh-CN', userAgent: 'feishu-clawdbot-bridge', }, })); return; } ``` Incoming message text is then forwarded to the agent: ```js let text = (JSON.parse(message.content)?.text || '').trim(); if (!text) return; // Group chat: check if we should respond if (message?.chat_type === 'group') { const mentions = Array.isArray(message?.mentions) ? message.mentions : []; text = text.replace(/@_user_\d+\s*/g, '').trim(); if (!text || !shouldRespondInGroup(text, mentions)) return; } const sessionKey = `feishu:${chatId}`; // Process asynchronously setImmediate(async () => { let placeholderId = ''; let done = false; // ... let reply = ''; try { reply = await askClawdbot({ text, sessionKey }); } catch (e) { reply = `(系统出错)${e?.message || String(e)}`; } ``` ### Technical Analysis The message handler checks message type and applies a response heuristic in group chats, but it does not authorize the sender or chat. There is no sender allowlist, chat allowlist, identity-to-role mapping, or approval check before forwarding text to the agent. Mentions, question punctuation, common request verbs, or a bot-like prefix are sufficient to trigger forwarding in a group. These are relevance heuristics, not access ...[truncated 1594 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Introduce explicit allowlists for authorized Feishu chat IDs and sender IDs. 2. Map each authorized identity to a narrowly defined role and permitted operation set. 3. Deny unknown users and groups by default. 4. Use the minimum gateway role and scopes needed to submit an agent message; avoid general `operator.read` and `operator.write` where narrower scopes exist. 5. Run the bridge against a dedicated, sandboxed agent with restricted tools and filesystem access. 6. Require explicit human approval before destructive, external, credential-related, or privileged tool calls. 7. Preserve and pass trusted sender identity metadata separately from untrusted message text. 8. Delimit remote text as untrusted content in the agent request rather than treating it as trusted system instruction. 9. Add rate limiting, audit logging, and alerts for rejected or sensitive requests. 10. Document the authorization model and require administrators to configure allowed chats before startup. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
skills/feishu-memory-recall/index.js:22
Finding
Feishu Bearer Token Is Cached Without Restrictive File Protections<![CDATA[ ## Vulnerability Details **File Location**: `skills/feishu-memory-recall/index.js:22-27, 34-59` **Vulnerability Type**: Insecure plaintext credential storage **Risk Level**: Medium ### Vulnerable Code ```js const MEMORY_DIR = path.resolve(__dirname, '../../memory'); const WORKSPACE = path.resolve(__dirname, '../..'); const TOKEN_PATH = path.join(MEMORY_DIR, 'feishu_token.json'); const GROUPS_FILE = path.join(MEMORY_DIR, 'active_groups.json'); const RECENT_EVENTS = path.join(WORKSPACE, 'RECENT_EVENTS.md'); ``` ```js async function getToken() { // Try cached token first if (fs.existsSync(TOKEN_PATH)) { try { const data = JSON.parse(fs.readFileSync(TOKEN_PATH, 'utf8')); if (data.token && data.expire > Date.now() / 1000) return data.token; } catch (e) {} } // Try to get fresh token const appId = process.env.FEISHU_APP_ID; const appSecret = process.env.FEISHU_APP_SECRET; if (!appId || !appSecret) throw new Error('No valid token. Set FEISHU_APP_ID and FEISHU_APP_SECRET.'); const res = await fetch(`${FEISHU_API}/auth/v3/tenant_access_token/internal`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ app_id: appId, app_secret: appSecret }) }); const data = await res.json(); if (data.code !== 0) throw new Error(`Token error: ${data.msg}`); const tokenData = { token: data.tenant_access_token, expire: Math.floor(Date.now() / 1000) + data.expire - 60 }; fs.writeFileSync(TOKEN_PATH, JSON.stringify(tokenData)); return tokenData.token; } ``` ### Technical Analysis The tenant bearer token is stored in plaintext using `fs.writeFileSync` without a restrictive `mode`, ownership validation, atomic creation, or symlink checks. Its effective permissions depend on the process umask and whether the destination already exists. The code also uses a predictable path inside the project-level `memory` directory. If ...[truncated 1175 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Prefer in-memory token caching and request a fresh token after process restart. 2. If persistent caching is required, store it under a private per-user configuration directory rather than the project tree. 3. Create the parent directory with mode `0700`. 4. Create or replace the token file atomically with mode `0600`. 5. Reject symbolic links and verify that the file is owned by the current user. 6. Avoid a separate `existsSync` check followed by a write, which introduces a time-of-check/time-of-use window. 7. Delete expired token files and avoid including token values in logs or errors. 8. Use an operating-system credential store where available. 9. Apply the minimum Feishu scopes required for message recall. ]]>

T08 · Insecure Dependencies

Warning
Location
skills/feishu-bridge/package.json:6
Finding
Persistent Bridge Uses Floating Dependencies Without a Lockfile<![CDATA[ ## Vulnerability Details **File Location**: `skills/feishu-bridge/package.json:6-13` **Vulnerability Type**: Non-reproducible dependency resolution for a privileged service **Risk Level**: Medium ### Vulnerable Code ```json "scripts": { "start": "node bridge.mjs", "setup": "node setup-service.mjs" }, "dependencies": { "@larksuiteoapi/node-sdk": "^1.56.1", "ws": "^8.18.0" } ``` ### Technical Analysis The bridge package has no lockfile in the audited project structure, and both dependencies use caret ranges. A later `npm install` can therefore resolve package versions different from those reviewed at publication time. This is particularly significant because the bridge is designed to run persistently and receives both a Feishu App Secret and a local gateway token. Third-party package code loaded by the bridge executes with the same privileges and can access the same process memory, environment, network, and filesystem. No evidence was found that the named packages are malicious. The vulnerability is the absence of deterministic dependency resolution and update review for a credential-bearing persistent process. ### Attack Path 1. A new package version is released within a permitted caret range, or an upstream package account is compromised. 2. A user runs the documented `npm install`. 3. npm resolves the new version because no committed lockfile fixes the dependency graph. 4. The bridge loads the changed dependency during startup. 5. Malicious dependency code executes with access to bridge credentials, Feishu message content, and the local user account. 6. The LaunchAgent can repeatedly restart and preserve execution of the compromised dependency. ### Impact Assessment A compromised dependency can access the Feishu App Secret, gateway token, incoming and outgoing messages, and local files available to the bridge account. It can also make arbitrary network requests and benefit from the bridge's launch-agent persistence. The potential sc ...[truncated 193 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Generate and commit a lockfile for the bridge package. 2. Use `npm ci` in deployment instructions rather than unrestricted `npm install`. 3. Pin reviewed direct dependency versions where practical. 4. Review lockfile changes and dependency release notes before updates. 5. Use automated dependency vulnerability and provenance checks. 6. Consider npm signature or provenance verification where supported. 7. Run the persistent bridge in a constrained environment with minimal filesystem and gateway privileges. 8. Establish a controlled rebuild and redeployment process instead of resolving dependencies directly on production workstations. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (121)

Credential Access

High
Category
Privilege Escalation
Content
export FEISHU_APP_ID="cli_a5xxxxxxxxxxxxx"
export FEISHU_APP_SECRET="your_app_secret_here"

# 方式二:.env 文件
cat > ~/.feishu-skills.env << 'EOF'
FEISHU_APP_ID=cli_a5xxxxxxxxxxxxx
FEISHU_APP_SECRET=your_app_secret_here
Confidence
83% confidence
Finding
The README instructs users to store long-lived application secrets in a plaintext local .env-style file under the home directory. Even with good intentions, this increases the chance of accidental disclosure through backups, misconfigured permissions, shell tooling, logs, or later reuse by other local processes.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The declared behavior is a broad Feishu skill suite, but the analysis indicates additional undeclared local file reads/writes and session-store access, including discovery of local OpenClaw session data. Undisclosed access to local memory logs, token caches, and session metadata materially changes the trust model and can expose sensitive data beyond the stated purpose.

MCP Config Access

High
Category
Agent Snooping
Content
# Install all skills
clawhub install feishu-skills-kit --dir ~/.claude/skills

# Configure MCP (edit ~/.claude/mcp.json)
# Add your FEISHU_APP_ID and FEISHU_APP_SECRET
# See mcp-config-template.json for reference
Confidence
95% confidence
Finding
The instructions direct users to place Feishu App ID and App Secret into ~/.claude/mcp.json, a shared local configuration path that may be readable by other skills or tools in the same environment. Storing long-lived API credentials in broadly accessible config files increases the risk of credential theft and abuse of the connected Feishu tenant.

MCP Config Access

High
Category
Agent Snooping
Content
"<FEISHU_DOC_MANAGER_INSTALL_PATH>": "feishu-doc-manager 仓库克隆后的本地路径",
    "<FEISHU_MCP_SERVER_PATH>": "飞书 MCP Server 的安装路径"
  },
  "_instructions": "1. 将此文件内容合并到 ~/.claude/mcp.json 中;2. 替换所有 <PLACEHOLDER> 为实际值;3. 删除 _comment、_placeholders、_instructions 字段;4. 重启 Claude Code"
}
Confidence
95% confidence
Finding
Skill accesses MCP server configuration files (mcp.json). MCP configs contain server URLs, authentication tokens, and tool definitions — reading them allows the skill to discover and potentially abuse other tool integrations.

MCP Config Access

High
Category
Agent Snooping
Content
"<FEISHU_DOC_MANAGER_INSTALL_PATH>": "feishu-doc-manager 仓库克隆后的本地路径",
    "<FEISHU_MCP_SERVER_PATH>": "飞书 MCP Server 的安装路径"
  },
  "_instructions": "1. 将此文件内容合并到 ~/.claude/mcp.json 中;2. 替换所有 <PLACEHOLDER> 为实际值;3. 删除 _comment、_placeholders、_instructions 字段;4. 重启 Claude Code"
}
Confidence
95% confidence
Finding
Skill accesses MCP server configuration files (mcp.json). MCP configs contain server URLs, authentication tokens, and tool definitions — reading them allows the skill to discover and potentially abuse other tool integrations.

MCP Config Access

High
Category
Agent Snooping
Content
"<FEISHU_DOC_MANAGER_INSTALL_PATH>": "feishu-doc-manager 仓库克隆后的本地路径",
    "<FEISHU_MCP_SERVER_PATH>": "飞书 MCP Server 的安装路径"
  },
  "_instructions": "1. 将此文件内容合并到 ~/.claude/mcp.json 中;2. 替换所有 <PLACEHOLDER> 为实际值;3. 删除 _comment、_placeholders、_instructions 字段;4. 重启 Claude Code"
}
Confidence
95% confidence
Finding
Skill accesses MCP server configuration files (mcp.json). MCP configs contain server URLs, authentication tokens, and tool definitions — reading them allows the skill to discover and potentially abuse other tool integrations.

Credential Access

High
Category
Privilege Escalation
Content
const { program } = require('commander');
const path = require('path');
const crypto = require('crypto');
require('dotenv').config({ path: require('path').resolve(__dirname, '../../.env'), quiet: true }); 

// Optimization: Use shared client with Auth Refresh & Retry
const { fetchWithAuth } = require('../feishu-common/index.js');
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
const { program } = require('commander');
const path = require('path');
const crypto = require('crypto');
require('dotenv').config({ path: require('path').resolve(__dirname, '../../.env'), quiet: true }); 

// Optimization: Use shared client with Auth Refresh & Retry
const { fetchWithAuth } = require('../feishu-common/index.js');
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Ssd 1

High
Confidence
96% confidence
Finding
The inline comment says a strict length check was removed 'to allow longer prompt injection via args if needed,' which semantically endorses facilitating prompt-injection content rather than merely discussing security. This is not a benign mention of security concepts; it describes a design choice that enables injection-style payload delivery through natural-language input.

Intent-Code Divergence

High
Confidence
98% confidence
Finding
This is a true command injection vulnerability. Although the message body is moved into a temporary file, the script still interpolates user-controlled values like --target, --color, and especially --title directly into a shell command string and executes it with execSync, which invokes a shell; embedded quotes or shell metacharacters can break out of the intended argument context and run arbitrary commands. In this skill context, the danger is elevated because Feishu automation is likely to run with user tokens, bot credentials, local filesystem access, and CI/agent permissions.

Credential Access

High
Category
Privilege Escalation
Content
**Publish app**: Submit version and publish, ensuring the app coverage includes target users/departments.

### 2. Get Access Token

Call the self-built app get tenant_access_token interface:
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
**Publish app**: Submit version and publish, ensuring the app coverage includes target users/departments.

### 2. Get Access Token

Call the self-built app get tenant_access_token interface:
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
**接口**:
```
DELETE /docx/v1/documents/{document_id}/blocks/{block_id}
```

**响应示例**:
Confidence
80% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Self-Modification

High
Category
Rogue Agent
Content
description: High-quality Feishu/Lark Docx writing via OpenClaw. Use when you want to turn Markdown into well-formatted Feishu Docx (headings, lists, nesting, code blocks) using feishu_docx_write_markdown; includes safe workflows, templates, and troubleshooting. Trigger on Feishu doc/docx links, “write to Feishu doc”, “generate a Feishu doc”, “append/replace docx”, “convert markdown to feishu doc”, or when users want consistently good doc formatting.
---

# Feishu Docx PowerWrite

This skill focuses on **reliably writing great-looking Feishu Docx** using OpenClaw’s Feishu OpenAPI tools.
Confidence
85% confidence
Finding
Skill modifies its own code, configuration, or behavior at runtime. Self-modification enables an agent to escalate privileges, disable safety constraints, or install persistent backdoors.

Credential Access

High
Category
Privilege Escalation
Content
## Authentication

All API calls require a tenant access token in the Authorization header:
```
Authorization: Bearer {tenant_access_token}
```
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
### 7. Delete Rows/Columns

**Endpoint:** `DELETE /sheets/v2/spreadsheets/{spreadsheet_token}/dimension_range`

**Request Body:** Same as insert
Confidence
80% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Credential Access

High
Category
Privilege Escalation
Content
self._token = None
        
    def _get_token(self) -> str:
        """Get tenant access token"""
        if self._token:
            return self._token
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
FEISHU_APP_ID=cli_a5xxxxxxxxxxxxx
FEISHU_APP_SECRET=your_app_secret_here
EOF
chmod 600 ~/.feishu-skills.env

# 方式三:安全文件(feishu-bridge 使用)
mkdir -p ~/.clawdbot/secrets
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Session Persistence

Medium
Category
Rogue Agent
Content
chmod 600 ~/.feishu-skills.env

# 方式三:安全文件(feishu-bridge 使用)
mkdir -p ~/.clawdbot/secrets
echo "your_app_secret_here" > ~/.clawdbot/secrets/feishu_app_secret
chmod 600 ~/.clawdbot/secrets/feishu_app_secret
```
Confidence
77% confidence
Finding
This duplicated finding covers the same persistent plaintext secret storage under ~/.clawdbot/secrets. Although intended as secure local storage, it still increases exposure by creating a durable, discoverable credential target on disk.

Session Persistence

Medium
Category
Rogue Agent
Content
chmod 600 ~/.feishu-skills.env

# 方式三:安全文件(feishu-bridge 使用)
mkdir -p ~/.clawdbot/secrets
echo "your_app_secret_here" > ~/.clawdbot/secrets/feishu_app_secret
chmod 600 ~/.clawdbot/secrets/feishu_app_secret
```
Confidence
77% confidence
Finding
This duplicated finding covers the same persistent plaintext secret storage under ~/.clawdbot/secrets. Although intended as secure local storage, it still increases exposure by creating a durable, discoverable credential target on disk.

Session Persistence

Medium
Category
Rogue Agent
Content
```bash
# 克隆 MCP Server
cd ~/.openclaw/workspace/skills 2>/dev/null || mkdir -p ~/.openclaw/workspace/skills && cd ~/.openclaw/workspace/skills
git clone https://github.com/Shuai-DaiDai/feishu-doc-manager.git
cd feishu-doc-manager
# 如果有 install.sh 则执行
Confidence
88% confidence
Finding
The README tells users to git clone a remote repository and conditionally execute install.sh with bash, which is arbitrary code execution from an external source. This is especially risky in a setup guide because users may run it without reviewing the script, and the script can persist changes, install additional components, or access local secrets.

Skill Enumeration

Medium
Category
Agent Snooping
Content
clawhub login

# 安装单个 skill
clawhub install feishu-doc-manager --dir ~/.claude/skills

# 批量安装所有飞书 skills
for skill in feishu-doc-manager feishu-docx-powerwrite feishu-doc-editor \
Confidence
85% confidence
Finding
Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Skill Enumeration

Medium
Category
Agent Snooping
Content
clawhub login

# 安装单个 skill
clawhub install feishu-doc-manager --dir ~/.claude/skills

# 批量安装所有飞书 skills
for skill in feishu-doc-manager feishu-docx-powerwrite feishu-doc-editor \
Confidence
85% confidence
Finding
Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Session Persistence

Medium
Category
Rogue Agent
Content
clawhub install feishu-doc-manager --dir ~/.claude/skills

# 批量安装所有飞书 skills
for skill in feishu-doc-manager feishu-docx-powerwrite feishu-doc-editor \
  feishu-messaging feishu-card feishu-sheets-skill feishu-bitable \
  feishu-bridge feishu-memory-recall feishu-leave-request; do
  clawhub install "$skill" --dir ~/.claude/skills --force
Confidence
60% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Session Persistence

Medium
Category
Rogue Agent
Content
**macOS 开机自启**:
```bash
FEISHU_APP_ID=cli_xxx node setup-service.mjs
launchctl load ~/Library/LaunchAgents/com.clawdbot.feishu-bridge.plist
```

---
Confidence
84% confidence
Finding
The plist reference indicates creation/loading of a LaunchAgent for recurring execution. While not inherently malicious, persistence mechanisms should be treated carefully because they survive restarts and can continuously access configured credentials or relay messages if the bridge is abused.

Static analysis

Detected: suspicious.dangerous_exec, suspicious.env_credential_access, suspicious.potential_exfiltration

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
skills/feishu-card/handle_event.js:19

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
skills/feishu-card/send_safe.js:42

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
skills/feishu-card/test.js:27

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
skills/feishu-memory-recall/recall.js:31

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
skills/feishu-memory-recall/index.js:27

Sensitive-looking file read is paired with a network send.

Warn
Code
suspicious.potential_exfiltration
Location
skills/feishu-memory-recall/index.js:38