Back to skill

Security audit

Lark/Feishu Sheets & Cloud File Download (with PDF extraction)

Security checks for vulnerabilities and agentic risk

Overview

The skill largely does what it claims, but it can use stored Feishu/Lark credentials to modify remote sheets, install Python packages, and overwrite local files without strong safeguards.

Review before installing. Use only with a narrowly permissioned Feishu/Lark app, avoid broad drive permissions unless needed, confirm every target spreadsheet/range before writes, run dry-run for mutations, and avoid using sensitive output paths because downloads and exports can overwrite files. The runtime PDF extraction path may install Python packages automatically, so install in an isolated environment or preinstall reviewed dependencies.

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)

T08 · Insecure Dependencies

Warning
Location
scripts/file_download.py:129
Finding
Automatic Installation of Unpinned Third-Party Packages<![CDATA[ ## Vulnerability Details **File Location**: `scripts/file_download.py:129-147` **Vulnerability Type**: Automatic installation and execution of unpinned dependencies **Risk Level**: Medium ### Vulnerable Code ```python def _pip_install(*packages: str): """Install packages via pip if not already present.""" subprocess.run( [sys.executable, "-m", "pip", "install", *packages], check=True, capture_output=True, ) def _ensure_import(module_name: str, pip_name: str | None = None): """Import a module, auto-installing via pip if missing.""" import importlib try: return importlib.import_module(module_name) except ImportError: pip_pkg = pip_name or module_name print(f"{pip_pkg} not found, installing via pip...", file=sys.stderr) _pip_install(pip_pkg) return importlib.import_module(module_name) ``` ### Technical Analysis When a PDF-processing module is unavailable, the Skill automatically invokes pip and installs the corresponding package from the Python environment's configured package index. The dependencies are not constrained to reviewed versions, protected by package hashes, or installed into a dedicated isolated environment. Package installation and subsequent import execute third-party code. Consequently, the effective code executed by the Skill can change after the Skill itself has been audited. The risk is affected by the integrity of the configured package index, dependency releases, transitive dependencies, and local pip configuration. This behavior is not required for the core file-download operation and exceeds the minimum actions necessary to download a Lark/Feishu file. It also modifies the active Python environment without obtaining explicit approval at execution time. ### Attack Path 1. A user invokes the file-download script for a PDF or requests text/image extraction. 2. One of the req ...[truncated 1035 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove runtime pip installation from document-processing code. 2. Declare all dependencies at Skill installation time using exact, reviewed version pins. 3. Use a lockfile and require cryptographic hashes for downloaded distributions. 4. Install dependencies inside a dedicated virtual environment rather than modifying the user's active Python environment. 5. Use an explicitly trusted package index and disable untrusted additional indexes. 6. Separate file downloading from optional PDF processing so downloading remains available without installing parsing libraries. 7. If runtime installation must remain, display the exact package, version, source, and expected changes, then require explicit user confirmation before proceeding. 8. Regularly review and update pinned dependencies through a controlled security-update process. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/file_download.py:111
Finding
Caller-Controlled Output Path Allows Destructive File Overwrite<![CDATA[ ## Vulnerability Details **File Location**: `scripts/file_download.py:111-126`; caller-controlled path accepted at `scripts/file_download.py:325` and used at line 345 **Vulnerability Type**: Arbitrary writable-path overwrite and unsafe output-file handling **Risk Level**: Medium ### Vulnerable Code ```python def _download_file(file_token: str, access_token: str, base: str, out_path: str, timeout: int = 300): """Download file content via Feishu Drive API and save to out_path. API: GET /open-apis/drive/v1/files/:file_token/download The response is binary file content (not JSON). """ endpoint = f"{base}/open-apis/drive/v1/files/{file_token}/download" headers = {"Authorization": f"Bearer {access_token}"} req = urllib.request.Request(endpoint, headers=headers, method="GET") with urllib.request.urlopen(req, timeout=timeout) as resp: data = resp.read() with open(out_path, "wb") as f: f.write(data) ``` The destination is supplied directly through the command-line interface: ```python ap.add_argument("--out", required=True, help="Output path for downloaded file") ``` It is then passed to the vulnerable write operation: ```python _download_file(file_token, access_token, base, args.out) ``` ### Technical Analysis The caller fully controls `out_path`. The script opens that path in `wb` mode, which creates a new file or truncates an existing file before writing downloaded content. It does not: - Restrict output to an approved download directory. - Reject absolute paths or directory traversal. - Resolve and validate the canonical destination. - Refuse existing files by default. - defend against symbolic links. - Use exclusive file creation. - Request confirmation before overwriting data. PDF processing also derives `.txt`, `_images`, and `_pages` destinations from the same untrusted output path, expanding the set of files and di ...[truncated 1343 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Restrict downloads to a dedicated, explicitly approved directory. 2. Resolve the destination with `Path.resolve()` and verify that it remains under the approved directory. 3. Reject absolute paths and traversal components when only a filename is expected. 4. Refuse symbolic-link destinations and validate parent directories against symlink traversal. 5. Create files exclusively using `open(path, "xb")` or equivalent atomic no-clobber semantics. 6. Require explicit user confirmation before replacing an existing file. 7. Write the response to a securely created temporary file first, then atomically rename it after validation. 8. Apply the same path validation and collision protections to derived `.txt`, `_images`, and `_pages` outputs. 9. Consider validating response size and content type before committing the downloaded data to disk. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (24)

Credential Access

High
Category
Privilege Escalation
Content
## Security & Credentials

This skill reads `appId` and `appSecret` from `~/.openclaw/openclaw.json` (`channels.feishu`) to obtain Lark/Feishu API access tokens. Credentials are only sent to official Feishu/Lark OpenAPI endpoints for token exchange — they are never logged, cached, or sent elsewhere.

## Files
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
A second description-behavior mismatch is present: the skill advertises broad Feishu sheet and file support, but the analysis indicates some declared user-facing operations may not actually exist or are only partially implemented. Even when not directly exploitable, this creates a security and governance problem by obscuring the true attack surface and encouraging use in contexts the skill may handle unsafely or unpredictably.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
A second description-behavior mismatch is present: the skill advertises broad Feishu sheet and file support, but the analysis indicates some declared user-facing operations may not actually exist or are only partially implemented. Even when not directly exploitable, this creates a security and governance problem by obscuring the true attack surface and encouraging use in contexts the skill may handle unsafely or unpredictably.

Credential Access

High
Category
Privilege Escalation
Content
| URL | Purpose |
|-----|---------|
| `https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal` | Obtain tenant access token |
| `https://open.feishu.cn/open-apis/sheets/v3/spreadsheets/*/sheets/query` | List sheet tabs |
| `https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/*/values_batch_get` | Read cell values |
| `https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/*/values_batch_update` | Write cell values |
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
## Authentication

### Get Tenant Access Token

```
POST /open-apis/auth/v3/tenant_access_token/internal
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Context-Inappropriate Capability

High
Confidence
97% confidence
Finding
The script auto-installs Python packages at runtime, which is an unjustified execution capability for a spreadsheet/file-management skill and introduces supply-chain risk. A downloaded package can execute code during installation or import, allowing compromise of the host environment and violating least-privilege expectations for the skill.

Session Persistence

Medium
Category
Rogue Agent
Content
# feishu-lark-sheets-edit

> OpenClaw skill — Read, write and manage Lark/Feishu Sheets, and download Lark/Feishu cloud files via OpenAPI.

## What it does
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.

Lp3

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding
The skill is user-invocable and clearly performs sensitive actions—reading local credential files, writing local files, making network requests, and invoking Python scripts—yet it declares no explicit tool scope or permissions boundary. This increases the risk of overbroad execution and makes it harder for the platform to constrain or audit what the skill may access or modify.

Session Persistence

Medium
Category
Rogue Agent
Content
---
name: feishu_lark_sheets_edit
description: "Read, write and manage Lark/Feishu Sheets (spreadsheets) and download Lark/Feishu cloud files via Lark OpenAPI. Reads Feishu app credentials (appId/appSecret) from ~/.openclaw/openclaw.json to authenticate with the Lark OpenAPI. Use when a user provides a Lark/Feishu sheet link (URL path like /sheets/TOKEN) and you need to fetch cell values, write/update cells, add/clone sheet tabs, convert to CSV/JSON, or feed the data into summaries/reports/analysis. Also use when a user provides a Lark/Feishu file link (URL path like /file/TOKEN) and needs to download the file (PDF, etc.) locally. Triggers: 'feishu sheet', 'lark sheet', 'spreadsheet', 'write to sheet', 'update sheet', 'export sheet', 'feishu file', 'lark file', 'download file', 'feishu download', 'lark download', 'cloud file'."
user-invocable: true
metadata: {"clawdbot": {"requires": {"bins": ["python3"]}, "os": ["darwin", "linux", "win32"], "files": ["scripts/sheets_export.py", "scripts/sheets_write.py", "scripts/file_download.py"], "reads": ["~/.openclaw/openclaw.json"], "note": "Reads appId/appSecret from ~/.openclaw/openclaw.json to obtain Lark/Feishu API tokens. PDF extraction auto-installs pdfplumber/pypdf/pymupdf via pip as needed, no system dependencies required."}}
---
Confidence
72% confidence
Finding
The skill relies on persistent local credentials stored in ~/.openclaw/openclaw.json and is directly invocable by user requests, creating a standing capability to access and act on external Feishu/Lark resources across sessions. That persistence increases the blast radius of accidental invocation, prompt-trigger abuse, or future code-path expansion because the skill can authenticate without fresh user approval.

Vague Triggers

Medium
Confidence
96% confidence
Finding
The trigger list includes very broad phrases like 'spreadsheet', 'download file', and 'cloud file', which can cause the skill to activate for routine user requests that do not clearly imply consent to use local credentials or perform external file/network operations. In a user-invocable skill that can read secrets and modify remote documents, over-triggering materially increases the chance of unintended sensitive actions.

Description-Behavior Mismatch

Medium
Confidence
91% confidence
Finding
The script's behavior goes beyond the declared cloud-file download purpose by automatically extracting text, extracting embedded images, and rendering pages from PDFs. That broadens data handling and local artifact creation, increasing exposure to sensitive-content persistence and parser attack surface when processing untrusted files.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
Automatically modifying the Python environment via pip without clear prior warning or consent is unsafe operationally and can have security consequences, especially on shared or privileged systems. Users invoking a file download tool would not reasonably expect it to install software, making this behavior deceptive and increasing the blast radius of any dependency compromise.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def _pip_install(*packages: str):
    """Install packages via pip if not already present."""
    subprocess.run(
        [sys.executable, "-m", "pip", "install", *packages],
        check=True,
        capture_output=True,
Confidence
95% confidence
Finding
This subprocess call invokes pip to install packages at runtime, which modifies the local environment and executes arbitrary package installation logic from external repositories. In the context of a file-download skill, this materially expands capability from downloading into software installation, creating supply-chain and unexpected code-execution risk if a dependency is malicious, compromised, or replaced.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
# 3. Try pdftotext (poppler)
    if shutil.which("pdftotext"):
        subprocess.run(
            ["pdftotext", "-layout", pdf_path, txt_path],
            check=True,
            capture_output=True,
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
# 2. Fallback to pdfimages (poppler)
    if shutil.which("pdfimages"):
        prefix = os.path.join(out_dir, "img")
        subprocess.run(
            ["pdfimages", "-png", pdf_path, prefix],
            check=True,
            capture_output=True,
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The script reads appId/appSecret from a local config file, exchanges them for a tenant access token, and then sends authenticated requests to the Feishu/Lark Sheets API. Although the module docstring describes these actions, the runtime path provides no user-facing prompt, warning, or log message before accessing credentials and transmitting spreadsheet data to a remote service.

Session Persistence

Medium
Category
Rogue Agent
Content
#!/usr/bin/env python3
"""Write / update Lark/Feishu Sheets via OpenAPI.

Complement to sheets_export.py (read-only). This script provides:
- Write cell values to a range (single or batch)
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.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The write command performs remote spreadsheet modification immediately after parsing inputs, with no confirmation prompt, no explicit warning, and no safeguard beyond a non-default --dry-run flag. In an agent skill context, this increases the chance of unintended or prompt-induced writes to external user data, making accidental integrity-impacting actions materially more likely.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The clone operation both creates a new sheet and copies data into it, causing multiple remote modifications without an explicit user-facing warning or confirmation. In an agent-driven environment, this is more dangerous because a single indirect instruction can duplicate potentially sensitive or stale data into a new tab, creating integrity and data-sprawl risks.

Natural-Language Policy Violations

Low
Confidence
90% confidence
Finding
The README switches from English to Chinese for the permissions setup section, which imposes a language-specific instruction block without user opt-in or an explicit note that the skill is intended for Chinese-speaking users. This can violate language/locale policy where documentation should remain user-selectable or clearly justified.

Missing User Warnings

Low
Confidence
83% confidence
Finding
The file includes app_secret and tenant access token usage in a markdown reference, but does not warn that these are sensitive credentials that must be protected and not exposed in logs or shared outputs. Under SQP-2 for markdown, omission of privacy or security-impact warnings around credential handling is in scope.

Missing User Warnings

Low
Confidence
87% confidence
Finding
This markdown file documents batch cell updates and adding sheet tabs, both of which change user data, but it provides no warning about data modification, overwrite risk, or the need to confirm the target sheet/range. For markdown files, SQP-2 applies when descriptions omit warnings about behaviors that could affect user data or system integrity.

Missing User Warnings

Low
Confidence
80% confidence
Finding
The script writes fetched spreadsheet contents to JSON or CSV files, which can persist potentially sensitive data on the local filesystem. While the CLI flags indicate output paths, there is no explicit warning in code comments or user-facing messaging that exported sheet data will be stored locally.

Missing User Warnings

Low
Confidence
92% confidence
Finding
The add-sheet command creates a new remote sheet tab without any direct warning or confirmation that a persistent change will be made to the user's spreadsheet. While lower impact than overwriting cell data, it still alters remote state and can be abused by a misdirected agent action or malformed user request.

Static analysis

No suspicious patterns detected.