T09 · Insecure Skill Coding Practices
- Location
scripts/feishu_token.py:40- Finding
Feishu access and refresh tokens are stored in a plaintext file without enforced restrictive permissions
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This Feishu document skill is mostly purpose-aligned, but it handles persistent Feishu credentials and document mutation with weak scoping and safeguards, so it belongs in Review before installation.
Install only if you are comfortable granting this skill access to Feishu documents under your user identity. Prefer reducing OAuth scopes to only what you need, avoid passing app secrets on the command line, protect or remove the cached token file after use, and manually confirm document IDs and block IDs before any update or delete operation.
scripts/feishu_token.py:40Feishu access and refresh tokens are stored in a plaintext file without enforced restrictive permissions
scripts/feishu_token.py:136Application secrets are accepted through process arguments and token material is disclosed in terminal output
SKILL.md:27The documented authorization flow requests search permissions not used by the implemented client
scripts/feishu_client.py:74The documented overwrite operation silently appends content instead of replacing it
The declared description says the skill is for document read/write operations, but the body also performs OAuth flows, token acquisition/refresh, and local credential caching. This mismatch is dangerous because operators may authorize the skill for simple document editing while overlooking that it can collect, refresh, and persist sensitive credentials.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
---
name: feishu-user
description: Feishu document operations (User Access Token version). Use user access token for authentication. When you need to read, create, write, or append Feishu documents.
---
# Feishishu document operations using useru User
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
---
name: feishu-user
description: Feishu document operations (User Access Token version). Use user access token for authentication. When you need to read, create, write, or append Feishu documents.
---
# Feishishu document operations using useru User
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
---
name: feishu-user
description: Feishu document operations (User Access Token version). Use user access token for authentication. When you need to read, create, write, or append Feishu documents.
---
# Feishishu document operations using useru User
The example initializes the client with an inline token placeholder and later instructs users to load tokens from a local config file, normalizing direct handling of bearer tokens in code and local files. In agent settings, this encourages insecure secret handling patterns that can lead to token leakage via source history, logs, prompts, or filesystem exposure.
client = FeishuClient(user_access_token="u-xxx")
## Get User Access Token
### Step 1: Get App Credentials from Feishu Open Platform
The method is documented as overwriting a document, but it actually appends content by delegating directly to append_doc. In an agent context, this semantic mismatch can cause unintended disclosure, duplication, or corruption of sensitive content because callers may rely on overwrite semantics when handling secrets or replacing stale data.
The skill documents network access, local file reads/writes, and token persistence, but does not declare any tool scope or permissions boundaries. In an agent environment, this increases the chance the skill will be invoked with broader capabilities than users expect, enabling unreviewed external requests and local credential storage.
The activation text is broad enough that the skill may trigger for many generic document-related requests without clearly constraining when it should access user-scoped Feishu data. Overbroad routing increases the likelihood of unnecessary exposure of personal documents and tokens in contexts where a simpler or read-only action would suffice.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
curl -X POST "https://open.feishu.cn/open-apis/authen/v1/access_token" \
-H "Content-Type: application/json" \
-d '{
"grant_type": "authorization_code",
The skill advertises overwrite, update, append, and delete operations without warning about destructive effects, persistence, or the possibility of modifying the wrong document/block. In an agent-assisted workflow, this can lead to accidental data loss or unauthorized changes to personal cloud documents.
The manifest description scopes the skill to reading, creating, writing, or appending Feishu documents. The code additionally exposes block-level retrieval, update, and deletion APIs, including destructive deletion of individual blocks, which is a more granular and broader capability than the stated document operations.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
}
}
resp = requests.put(url, json=payload, headers=self.headers)
data = resp.json()
if data.get("code") != 0:
This code file defines a delete operation that permanently removes a document block via an HTTP DELETE request. Although the docstring names the action as deletion, there is no confirmation prompt, cautionary notice, or explicit warning to the caller about the destructive effect.
The skill is described as document operations, but this file adds OAuth token acquisition and refresh logic, expanding the capability surface into credential handling and persistence. That mismatch increases security risk because users may not expect the skill to manage long-lived authentication material, making misuse or overscoped access easier to overlook.
The code writes access and refresh tokens to a predictable local config file in the user's home directory without any access control hardening or encryption. If the host is multi-user, backed up insecurely, or otherwise compromised, these tokens can be stolen and used to access the victim's Feishu data until revoked or expired.
The script posts app_id, app_secret, and auth code to the Feishu token endpoint, which is a sensitive network transmission. This is central to the script's purpose, but there is no explicit disclosure in the usage/help text or docstrings that these secrets will be sent to a remote service.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
"app_secret": self.app_secret
}
resp = requests.post(url, json=payload)
data = resp.json()
if data.get("code") != 0:
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
"app_secret": self.app_secret
}
resp = requests.post(url, json=payload)
data = resp.json()
if data.get("code") != 0:
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
"app_secret": self.app_secret
}
resp = requests.post(url, json=payload)
data = resp.json()
if data.get("code") != 0:
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
"app_secret": self.app_secret
}
resp = requests.post(url, json=payload)
data = resp.json()
if data.get("code") != 0:
Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.
"app_secret": self.app_secret
}
resp = requests.post(url, json=payload)
data = resp.json()
if data.get("code") != 0:
Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.
"app_secret": self.app_secret
}
resp = requests.post(url, json=payload)
data = resp.json()
if data.get("code") != 0:
At this point the script persists both access and refresh tokens locally without explicit user warning or consent, creating a silent credential retention risk. Refresh tokens are especially sensitive because they can mint new access tokens, so theft of the config file can lead to durable account access.
The refresh flow sends refresh_token, app_id, and app_secret to the remote refresh endpoint. While expected for token refresh, the script does not clearly warn in advance that locally stored credentials will be transmitted over the network during this operation.
Natural-language guidance in this file is exclusively Chinese, including the module description and usage instructions. Under the stated policy, forcing one language without opt-in or justification can be a locale/language policy issue.
No suspicious patterns detected.