Back to skill

Security audit

feishu-doc-reviewer

Security checks for vulnerabilities and agentic risk

Overview

The skill largely matches its Feishu document-review purpose, but it can immediately edit/delete live documents and has an unsafe CLI wrapper that can execute crafted input as Python code.

Install only if you are comfortable giving this skill Feishu document/comment read-write access. Use a test document first, grant the Feishu app access only to documents you intend it to edit, avoid the run-tool.sh wrapper until it is fixed, and require human review before any update, deletion, reply, or resolve action.

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 (2)

T09 · Insecure Skill Coding Practices

Error
Location
run-tool.sh:42
Finding
Arbitrary Python Code Execution Through CLI Argument Interpolation<![CDATA[ ## Vulnerability Details **File Location**: `run-tool.sh:42-52` **Additional Affected Locations**: `run-tool.sh:12-21`, `run-tool.sh:27-36`, `run-tool.sh:58-68` **Vulnerability Type**: Python code injection through dynamically constructed source code **Risk Level**: High ### Vulnerable Code ```bash "update_block") DOCUMENT_TOKEN=$1 BLOCK_ID=$2 NEW_TEXT=$3 python3 -c " import sys sys.path.insert(0, '.') from src.feishu_api import FeishuClient import json api = FeishuClient() result = api.update_block('$DOCUMENT_TOKEN', '$BLOCK_ID', '''$NEW_TEXT''') print(json.dumps(result, indent=2, ensure_ascii=False)) " ;; ``` The same unsafe construction is also used by the `list_comments`, `get_block`, and `reply_comment` command branches. ### Technical Analysis Command-line arguments are inserted directly into a string that is subsequently interpreted as Python source by `python3 -c`. Shell quoting does not make these values safe inside the generated Python program. An attacker-controlled document token, block ID, comment ID, content value, or replacement text can contain quote delimiters and additional Python syntax. The crafted value can terminate the intended Python string literal and introduce arbitrary statements that are executed when the wrapper invokes Python. The `update_block` and `reply_comment` branches are particularly exposed because they accept free-form document or comment text. The flaw is not limited to shell metacharacters: even if shell expansion is avoided, the resulting data remains executable Python syntax. ### Attack Path 1. An attacker supplies maliciously structured text or an identifier through a request that causes an Agent or user to invoke `run-tool.sh`. 2. The wrapper assigns the value to a shell variable without validating its expected format. 3. The variable is interpolated into the source string passed to `python3 -c`. 4. Quote delimiters in the value escape the intended Python string. 5. Injected Python state ...[truncated 1099 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove all dynamic construction of Python source from shell arguments. 2. Replace `python3 -c` with a normal Python CLI implemented using `argparse`. 3. If the shell wrapper must remain, pass values as positional arguments to a static Python program and read them from `sys.argv`. 4. Validate structured identifiers using strict allowlists. For example, document tokens, block IDs, and comment IDs should only permit the character set and length documented by Feishu. 5. Treat document and comment text as opaque data and never embed it into executable source. 6. Add regression tests containing single quotes, triple quotes, newlines, backslashes, and Python-like text to confirm that these inputs remain data. 7. Run the Skill under a dedicated, minimally privileged operating-system account and limit access to unrelated files. A safe design is: ```bash python3 process_tool.py update_block \ --document-token "$DOCUMENT_TOKEN" \ --block-id "$BLOCK_ID" \ --new-text "$NEW_TEXT" ``` The Python program should then pass parsed argument values directly to `FeishuClient.update_block` without using `eval`, `exec`, or dynamically generated source code. ]]>

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding
Unpinned Dependencies Permit Unreviewed Supply-Chain Changes<![CDATA[ ## Vulnerability Details **File Location**: `requirements.txt:1-3` **Vulnerability Type**: Mutable and unverified third-party dependency resolution **Risk Level**: Medium ### Vulnerable Code ```text requests python-dotenv mcp>=1.0.0; python_version>="3.10" ``` The documented installation process executes: ```bash pip install -r requirements.txt ``` ### Technical Analysis The project does not pin exact versions of `requests` or `python-dotenv`, and accepts any compatible `mcp` release at or above version 1.0.0. It also provides no package hashes or lock file. As a result, identical installation commands can resolve to different package versions over time. A compromised upstream release, malicious package takeover, dependency-confusion condition in the installation environment, or newly introduced vulnerable release could be installed without any change to this repository. This is especially significant because these dependencies execute in the same Python environment as the Skill and can access Feishu credentials, document content, and the Skill process's local permissions. ### Attack Path 1. A user follows the documented installation command. 2. The package resolver selects the latest release satisfying the broad requirements. 3. An upstream package, transitive dependency, package index, or configured higher-priority index supplies a compromised or unexpectedly vulnerable release. 4. The unreviewed package is installed because no exact version or integrity hash rejects it. 5. Package code executes during installation or when imported by the Skill. 6. The compromised code gains access to the Skill runtime, including environment variables, Feishu API traffic, and local files accessible to the process. ### Impact Assessment A successful supply-chain compromise could obtain the same privileges as the Skill process, including: - Reading the Feishu App ID and App Secret. - Capturing tenant access tokens. - Reading or altering documents and com ...[truncated 443 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin every direct dependency to an exact reviewed version. 2. Generate and commit a lock file that also constrains transitive dependencies. 3. Use hash verification, such as a requirements file generated with `pip-compile --generate-hashes`, and install with `pip install --require-hashes`. 4. Install exclusively from an approved package index over TLS and disable untrusted extra indexes. 5. Use an isolated virtual environment with minimal filesystem and network privileges. 6. Add automated dependency vulnerability and provenance scanning. 7. Review and test dependency updates before changing the lock file. 8. Consider reproducible build artifacts or an internally controlled package mirror for deployment. An exact version pin alone improves reproducibility, but cryptographic hashes are also needed to verify package artifact integrity. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Output HandlingUnvalidated Output Injection, Cross-Context Output, Unbounded Output
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
Findings (43)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
This mismatch is security-relevant because the documented purpose understates materially destructive and privilege-sensitive behaviors, including deletion, comment resolution, insertion, and credentialed API access. When a skill presents itself as generic read/write review tooling but also performs state changes beyond that description, users and orchestrators may authorize it without understanding the full blast radius.

Tp4

High
Category
MCP Tool Poisoning
Confidence
86% confidence
Finding
This mismatch is security-relevant because the documented purpose understates materially destructive and privilege-sensitive behaviors, including deletion, comment resolution, insertion, and credentialed API access. When a skill presents itself as generic read/write review tooling but also performs state changes beyond that description, users and orchestrators may authorize it without understanding the full blast radius.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
This mismatch is security-relevant because the documented purpose understates materially destructive and privilege-sensitive behaviors, including deletion, comment resolution, insertion, and credentialed API access. When a skill presents itself as generic read/write review tooling but also performs state changes beyond that description, users and orchestrators may authorize it without understanding the full blast radius.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
This mismatch is security-relevant because the documented purpose understates materially destructive and privilege-sensitive behaviors, including deletion, comment resolution, insertion, and credentialed API access. When a skill presents itself as generic read/write review tooling but also performs state changes beyond that description, users and orchestrators may authorize it without understanding the full blast radius.

Credential Access

High
Category
Privilege Escalation
Content
from dotenv import load_dotenv

project_root = Path(__file__).resolve().parents[1]
load_dotenv(dotenv_path=project_root / ".env")

FEISHU_APP_ID = os.getenv("FEISHU_APP_ID")
FEISHU_APP_SECRET = os.getenv("FEISHU_APP_SECRET")
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
raise ValueError(
                "❌ 未找到飞书 App ID 或 Secret!\n"
                "请您先前往飞书开放平台 (https://open.feishu.cn/app/) 创建一个企业自建应用。\n"
                "创建后,将获取到的 App ID 和 App Secret 填入 .env 文件或作为环境变量传入。"
            )

    def get_tenant_access_token(self):
Confidence
60% 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
"""
        删除块内容(通过清空内容实现)
        
        注意:飞书 docx API 没有直接的 DELETE /blocks/{block_id} 接口。
        实际做法是用 PATCH 更新块,将内容设置为空字符串。
        
        Args:
Confidence
90% confidence
Finding
The presence of a tool-accessible deletion primitive that clears arbitrary document blocks creates a strong parameter-abuse risk: any caller able to influence `document_id` and `block_id` can destroy content. In an agent skill, this is more dangerous because user prompts or upstream tool orchestration may be manipulated into invoking destructive actions on unintended targets.

Unvalidated Output Injection

High
Category
Output Handling
Content
try:
            response = requests.post(url, headers=self._get_headers(), json=payload)
            print(f"Insert blocks status: {response.status_code}")
            print(f"Insert blocks response: {response.text[:500]}")
            response.raise_for_status()
            return response.json()
Confidence
100% confidence
Finding
Model output is used without validation or sanitization. Unvalidated output injected into downstream contexts (SQL, shell, HTML) enables injection attacks and arbitrary code execution.

Unvalidated Output Injection

High
Category
Output Handling
Content
try:
            response = requests.post(url, headers=self._get_headers(), json=payload)
            print(f"Insert blocks status: {response.status_code}")
            print(f"Insert blocks response: {response.text[:500]}")
            response.raise_for_status()
            return response.json()
        except Exception as e:
Confidence
100% confidence
Finding
Logging `response.text[:500]` prints untrusted remote server content directly to logs/console. If the response includes sensitive metadata, document fragments, tokens in error messages, or terminal control characters, this can leak data or enable log/terminal manipulation in downstream environments.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The document advertises capabilities to update block text and reply to comments, but does not clearly warn users that these are live write operations affecting real Feishu documents. Without an explicit warning about side effects, users or downstream agents may treat these actions like harmless reads, leading to accidental content modification, unauthorized comment responses, or destructive edits in shared documents.

Vague Triggers

Medium
Confidence
92% confidence
Finding
The integration guide says users can simply describe a task in conversation and the agent will automatically call tools, but it does not define clear activation boundaries, confirmation requirements, or limits on when write-capable actions may run. In a skill that can edit documents and reply to comments, this broad trigger model increases the chance of unintended tool execution, prompt-induced actions from document content, or user requests being interpreted as authorization to perform irreversible changes.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The README advertises full-document Markdown export for agent context but does not warn that this may expose the entire document, including sensitive business content, to the host model or any connected LLM. In this skill's context, exporting full documents is more dangerous because the tool is specifically designed to feed document contents into an AI workflow, increasing the chance of unnecessary data disclosure beyond the minimally needed paragraph.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The README explicitly promotes remote document modification and comment reply capability, but it does not clearly warn users that an agent can change live Feishu content. In an agent-skill context, this creates a real safety risk because users may enable the skill without appreciating that model mistakes, prompt injection from document comments, or mis-targeted operations can overwrite production documents.

Lp3

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding
The skill advertises and documents network/API access plus use of environment-based credentials, but the manifest shown in SKILL.md does not declare any explicit tool scope such as permissions or allowed-tools. That creates a transparency and least-privilege problem: an agent or reviewer cannot easily tell what capabilities are intended, and overly broad runtime access could enable unintended external actions against Feishu documents.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The documentation encourages automated document reads, writes, and deletions using app credentials without warning about privacy exposure, irreversible edits, or review requirements. In a document-review skill, this context increases danger because sensitive business content may be exported, altered, or resolved automatically under an agent's control.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The CLI examples directly show destructive operations that can delete selected text or clear entire blocks, but they do not warn that these actions alter live documents and may be irreversible. This is dangerous because users or agents may copy-paste commands into production documents without understanding the scope of deletion.

External Transmission

Medium
Category
Data Exfiltration
Content
response = requests.patch(url, headers=headers, json={"is_solved": True})

# 错误 ❌
response = requests.put(url, headers=headers, json={"is_solved": True})  # 返回 404
```

## 常见问题
Confidence
70% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The script can delete whole blocks or remove selected text and then automatically reply to and resolve the comment with no confirmation, preview, authorization gate, or dry-run step. In a document-editing skill, this creates a real integrity risk: a mistaken comment/block match, bad automation decision, or maliciously crafted invocation could silently alter or destroy document content and mark the issue as completed.

External Transmission

Medium
Category
Data Exfiltration
Content
}
    }
    
    reply_response = requests.post(reply_url, headers=headers, json=reply_payload, params=params)
    reply_result = reply_response.json()
    
    if reply_result.get('code') == 0:
Confidence
80% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
}
    }
    
    reply_response = requests.post(reply_url, headers=headers, json=reply_payload, params=params)
    reply_result = reply_response.json()
    
    if reply_result.get('code') == 0:
Confidence
80% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The function performs state-changing remote actions by posting a reply and then resolving the comment automatically, with no confirmation gate, dry-run mode, or authorization check at the point of action. In an agent skill context, this is dangerous because an upstream prompt, wrong document token/comment ID, or automation mistake can cause unintended writes to user documents and silently mark feedback as completed.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The script exposes write-capable operations (`update_block` and `reply_comment`) that directly modify remote Feishu documents and comments without any confirmation, dry-run mode, or explicit safety interlock. In an agent setting, this increases the risk of unintended or prompt-induced changes being committed immediately to user data, especially because the tool is specifically designed for both reading and writing live documents.

External Transmission

Medium
Category
Data Exfiltration
Content
"app_secret": self.app_secret
        }
        try:
            response = requests.post(url, json=payload)
            response.raise_for_status()
            data = response.json()
            if data.get("code") != 0:
Confidence
80% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
State-changing methods such as block updates and effective deletion are executed immediately against the remote document with no built-in confirmation, dry-run, or user warning. In an agent setting, this increases the chance of accidental or manipulated destructive edits to live documents.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The skill exposes a destructive content-removal capability via `delete_block`, implemented as a remote PATCH that clears a document block. The declared skill purpose is document review read/write/reply, so hidden deletion broadens the authority surface and can be abused to remove content without the user's clear expectation.

Static analysis

No suspicious patterns detected.