Back to skill

Security audit

Feishu File Sender 1.0.9

Security checks for vulnerabilities and agentic risk

Overview

This skill does what it says, but it handles Feishu credentials and file uploads with a real workspace-matching weakness that could use the wrong agent's Feishu account.

Review before installing. Use only with a least-privileged Feishu bot, restrict who can invoke it, prefer sending only to the current inbound chat, and avoid using it where sibling or overlapping workspace paths exist until the cwd-to-workspace check is fixed. Do not run it on sensitive paths unless you intentionally want those files uploaded to Feishu.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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)

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/feishu_file_sender.py:25
Finding
Workspace Prefix Confusion Permits Cross-Agent Feishu Account Selection## Vulnerability Details **File Location**: `scripts/feishu_file_sender.py`, lines 25-40 **Vulnerability Type**: Improper workspace authorization boundary validation **Risk Level**: Medium ### Vulnerable Code ```python def resolve_agent_id(config: Dict[str, Any]) -> str: cwd = Path.cwd().resolve() best_match = (0, None) for agent in config.get("agents", {}).get("list", []): workspace = agent.get("workspace") agent_id = agent.get("id") if not workspace or not agent_id: continue workspace_path = Path(workspace).resolve() if str(cwd).startswith(str(workspace_path)): match_len = len(str(workspace_path)) if match_len > best_match[0]: best_match = (match_len, agent_id) if best_match[1]: return best_match[1] raise RuntimeError("Unable to resolve agent id from workspace path") ``` ### Technical Analysis The current working directory is associated with an agent by performing a raw string-prefix comparison: ```python str(cwd).startswith(str(workspace_path)) ``` A string prefix is not equivalent to a filesystem ancestry check. For example, if an agent workspace is `/srv/agents/finance`, a separate directory named `/srv/agents/finance-attacker` also passes this test. The resulting agent ID is subsequently used to select a Feishu account binding and read its `appId` and `appSecret`. Therefore, workspace resolution serves as an authorization boundary, but the implementation does not accurately verify that the process is inside the selected workspace. The credentials are not printed or returned directly. Nevertheless, the script uses the incorrectly selected credentials to obtain a tenant access token, upload a caller-selected local file, and send it to a caller-selected Feishu recipient. This exposes the victim agent's Feishu bot authority as a confused-deputy capability. ### Attack Path ...[truncated 1698 chars]
Remediation
## Remediation Suggestions Replace string-prefix matching with a component-aware filesystem ancestry test: ```python workspace_path = Path(workspace).expanduser().resolve() if cwd == workspace_path or workspace_path in cwd.parents: match_len = len(workspace_path.parts) if match_len > best_match[0]: best_match = (match_len, agent_id) ``` Additional hardening should include: 1. Prefer receiving the active agent ID from a trusted runtime context rather than inferring authorization from the current working directory. 2. Verify that the trusted agent ID, workspace, and Feishu account binding are mutually consistent before reading credentials. 3. Reject ambiguous workspace configurations, including duplicate or overlapping workspace roots. 4. Restrict selectable recipients to the current inbound conversation unless an explicit policy grants broader delivery rights. 5. Consider restricting file paths to the authenticated agent's workspace or a dedicated output directory. 6. Add tests covering sibling paths such as `/workspace`, `/workspace-evil`, `/workspace2`, and legitimate descendants such as `/workspace/output`.

T08 · Insecure Dependencies

Note
Location
README.md:39
Finding
Unpinned Third-Party Dependency Installation Creates Supply-Chain Exposure## Vulnerability Details **File Location**: `README.md`, lines 39-43 **Vulnerability Type**: Unpinned third-party package installation **Risk Level**: Low ### Vulnerable Instructions ```markdown ## Install ```bash python3 -m pip install requests ``` ``` The corresponding runtime import occurs in `scripts/feishu_file_sender.py`: ```python import requests ``` ### Technical Analysis The installation instructions retrieve `requests` without a version constraint, lock file, or cryptographic hash. Consequently, the installed artifact depends on the package index state at installation time and is not reproducible from the audited project contents. No evidence indicates that the legitimate `requests` package is currently malicious. The issue is that the project does not constrain or verify the exact dependency artifact. A compromised package-index account, malicious future release, index substitution, or compromised configured package mirror could therefore introduce code that was not part of this audit. This exposure is especially relevant because the dependency executes in a process that reads Feishu application credentials from `~/.openclaw/openclaw.json`, receives tenant access tokens, reads caller-selected local files, and performs network requests. ### Attack Path 1. An operator follows the documented `python3 -m pip install requests` instruction. 2. The configured package index or mirror supplies a compromised or otherwise unsafe release. 3. Pip installs that release without validating it against a project-maintained hash. 4. Malicious package code may execute during installation or when the sender imports `requests`. 5. Runtime code executes with the privileges of the installer or skill process and may access the OpenClaw configuration, Feishu credentials, uploaded files, and access tokens. This attack path is contingent on compromise or substitution of the dependency source; the audited repository it ...[truncated 729 chars]
Remediation
## Remediation Suggestions 1. Declare dependencies in a version-controlled requirements or lock file. 2. Pin `requests` and its transitive dependencies to reviewed versions. 3. Use hash verification, for example: ```text requests==REVIEWED_VERSION --hash=sha256:REVIEWED_DISTRIBUTION_HASH ``` 4. Install with hash enforcement: ```bash python3 -m pip install --require-hashes -r requirements.txt ``` 5. Review and update pins regularly using automated vulnerability scanning. 6. Install only from an explicitly trusted HTTPS package index or controlled internal mirror. 7. Document `requests` in the Skill runtime requirements so dependency installation is explicit and reproducible. 8. Avoid running pip or the sender as root; use a dedicated, least-privileged virtual environment.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (10)

Credential Access

High
Category
Privilege Escalation
Content
- `channels.feishu.accounts.*.appId`
- `channels.feishu.accounts.*.appSecret`

这些凭证仅用于获取 tenant access token 并发送文件。技能不会存储或向其他地方传输凭证。

This skill reads Feishu credentials from your local OpenClaw config (`~/.openclaw/openclaw.json`):
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
- `channels.feishu.accounts.*.appId`
- `channels.feishu.accounts.*.appSecret`

这些凭证仅用于获取 tenant access token 并发送文件。技能不会存储或向其他地方传输凭证。

This skill reads Feishu credentials from your local OpenClaw config (`~/.openclaw/openclaw.json`):
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
- `channels.feishu.accounts.*.appId`
- `channels.feishu.accounts.*.appSecret`

这些凭证仅用于获取 tenant access token 并发送文件。技能不会存储或向其他地方传输凭证。

This skill reads Feishu credentials from the local OpenClaw config
(`~/.openclaw/openclaw.json`) on the machine where it runs:
Confidence
84% confidence
Finding
The skill is designed to read Feishu appId/appSecret from ~/.openclaw/openclaw.json and use them to obtain an access token. Even if this is for legitimate functionality, accessing local credentials is a sensitive capability: compromise of the skill, misuse by another agent, or weak isolation could expose secrets and enable unauthorized API actions.

Credential Access

High
Category
Privilege Escalation
Content
- `channels.feishu.accounts.*.appId`
- `channels.feishu.accounts.*.appSecret`

These values are used only to obtain a tenant access token and send the file.
The skill does not store or transmit credentials anywhere else.

## 备注 | Notes
Confidence
80% confidence
Finding
The documentation confirms the skill uses locally stored Feishu secrets to mint an access token and send data externally. In context, that makes the credential access operationally necessary, but still security-relevant because the same capability can be abused to impersonate the Feishu app, send unauthorized messages, or access tenant resources if the environment is not tightly controlled.

Lp3

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill explicitly performs file reads, environment-variable access, and outbound network calls, but the manifest does not declare any corresponding tool scope or permissions boundary. This is dangerous because users and hosting frameworks cannot clearly audit or constrain the skill’s capabilities, increasing the risk of unintended secret access or exfiltration through normal execution paths.

External Transmission

Medium
Category
Data Exfiltration
Content
def get_tenant_access_token(app_id: str, app_secret: str) -> str:
    resp = requests.post(
        FEISHU_TOKEN_URL,
        json={"app_id": app_id, "app_secret": app_secret},
        timeout=15,
Confidence
80% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Tainted flow: 'data' from requests.post (line 130, network input) → requests.post (network output)

Medium
Category
Data Flow
Content
"file_type": file_type,
            "file_name": file_path.name,
        }
        resp = requests.post(
            FEISHU_UPLOAD_URL,
            headers=headers,
            data=data,
Confidence
65% confidence
Finding
Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

External Transmission

Medium
Category
Data Exfiltration
Content
"msg_type": "file",
        "content": json.dumps({"file_key": file_key}),
    }
    resp = requests.post(
        FEISHU_SEND_MSG_URL,
        headers=headers,
        params=params,
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
88% confidence
Finding
The script silently reads Feishu app credentials from local OpenClaw configuration and immediately uses them for outbound API calls. In an agent environment, undisclosed use of locally stored secrets can surprise operators, widen the blast radius of misuse, and enable unauthorized messaging/file transfer under the configured tenant identity.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The script exfiltrates a local file to Feishu as its core behavior, but it provides no user-facing confirmation, preview, allowlist, or safety interlock before transmission. In an agent-skill context, this increases the chance of accidental disclosure of sensitive local files if the skill is invoked on the wrong path or with attacker-influenced inputs.

Static analysis

No suspicious patterns detected.