T09 · Insecure Skill Coding Practices
- Location
scripts/billing.py:13- Finding
Hard-Coded SkillPay API Credential
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill matches its Feishu chat-memory purpose, but it should be reviewed carefully because it stores sensitive group chat text and has unsafe billing credential and billing-verification behavior.
Install only if you are authorized to process the Feishu groups involved and are comfortable storing raw chat-derived records locally. The publisher should remove and rotate the embedded SkillPay key, fail closed on billing errors, add explicit consent and charge confirmations, and provide retention, deletion, and file-permission controls before broad use.
scripts/billing.py:13Hard-Coded SkillPay API Credential
scripts/billing.py:28Fail-Open Billing Verification Allows Payment Bypass
scripts/listener.py:174Sensitive Feishu Records Stored Without Explicit File Access Controls
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
f"{FEISHU_BASE}/auth/v3/tenant_access_token/internal",
data=payload, headers={"Content-Type": "application/json"}, method="POST")
try:
with urllib.request.urlopen(req, timeout=10) as r:
result = json.loads(r.read().decode())
if result.get("code") != 0:
err(f"获取飞书 token 失败: {result.get('msg')}")
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
f"{FEISHU_BASE}{path}",
headers={"Authorization": f"Bearer {token}", "Content-Type": "application/json"})
try:
with urllib.request.urlopen(req, timeout=15) as r:
result = json.loads(r.read().decode())
if result.get("code") not in (0, None):
err(f"飞书错误 {result.get('code')}: {result.get('msg')}")
This code does not implement the declared core functionality of extracting, storing, querying, or analyzing Feishu group messages. Its primary purpose is billing management only. While the description mentions that analysis/advice calls are billed via SkillPay, this chunk goes beyond a generic supporting detail by exposing explicit billing capabilities: charging accounts, checking balances, and creating payment links. Those are undeclared operational capabilities in the user-facing description and are materially different from the advertised chat-analysis behavior. Therefore this chunk is a description/behavior mismatch.
This is a description-to-code mismatch because the declared purpose describes a substantially richer end-user capability than the code actually provides. The script is a utility CLI for Feishu message retrieval and local record storage. It can search chats, pull raw messages, save already-analyzed records, and list saved records. The comments explicitly state it is 'pure data operations' and 'does not call LLM'; fetch_raw returns text 'for AI analysis' and save_records stores records 'already analyzed by AI.' Therefore the core declared features—AI summaries, insights, advice, industry/custom knowledge packs, and per-call billing—are not present in this code chunk. While this code could be a backend component supporting the larger skill, the supplied chunk by itself does not accurately represent the declared end-to-end behavior.
The description promises a chat-memory and analytics skill centered on Feishu group messages, with retrieval and AI analysis capabilities. The actual code chunk is limited to onboarding/configuration for knowledge packs: checking for a context file, loading one of several built-in markdown files, or saving supplied text as a custom context file. While built-in/custom industry packs mentioned in the description are partially reflected, the primary advertised functionality—message extraction, storage, querying, summarization, and advice—is absent from this code. Therefore the code chunk’s behavior is materially narrower and different from the declared purpose.
This code chunk only implements read-side local retrieval from a file named feishu-memory-records.jsonl. The search command does substring keyword matching over existing record fields, and list_records filters/sorts records by date. That partially overlaps with the declared 'query it' functionality, but the broader declared description emphasizes extracting/storing Feishu group discussions and generating AI insights/advice with domain packs and paid analysis. None of those major capabilities appear in this code. Because the actual code's primary purpose is much narrower and lacks several headline features from the description, this is a material description-behavior mismatch.
The skill is designed to fetch, analyze, store, query, and summarize group chat messages, but it does not present a clear privacy notice, consent requirement, retention policy, or warning about handling potentially sensitive third-party communications. This context makes the issue more dangerous because group messages often contain personal data, confidential business content, and statements from people who did not directly consent to storage and later AI analysis.
The file contains a hardcoded SkillPay API key directly in source code, which is a real secret that authorizes billing actions. If the repository, package, logs, or deployed artifact are exposed, an attacker could use the credential to issue unauthorized billing requests or query billing-related data, making this especially dangerous in a payment-enabled skill.
The skill declares operational scripts that read environment/configuration, perform file I/O, and likely make network calls to Feishu and billing services, yet it does not declare any explicit tool scope or allowed-tools boundary. That weakens least-privilege controls and makes it harder for a host system to restrict the skill to only the minimum required capabilities.
The skill instructs persistent storage and later reuse of group-message-derived records and generated summaries, creating an intentional retention channel for potentially sensitive chat content. In a group-memory product this is functionally expected, but without minimization, retention limits, or access controls it increases the chance of later data leakage, overexposure in summaries, or misuse across sessions.
The skill explicitly directs saving raw message text together with metadata and derived summaries into persistent records for later querying and summarization. Raw text retention materially increases exposure because it may contain credentials, personal data, legal content, internal strategy, or third-party statements that can later be surfaced out of context or to unauthorized users.
The advice trigger includes generic phrases such as 'give me some advice' and 'help me think through this,' which are broad enough to match ordinary conversation and unintentionally activate a billed or sensitive workflow. In this skill, that is more dangerous because advice generation is explicitly chargeable and may also rely on previously stored chat data, creating both financial and privacy risk from accidental invocation.
The file’s headings, instructions, templates, and keyword list are all Chinese-language only, which can amount to a language policy violation if the skill implicitly forces one language without user opt-in. There is no statement that the skill is region-specific or that users may choose another language/locale.
This knowledge pack explicitly targets legal-team group discussions and instructs extraction and storage of highly sensitive legal information such as contract status, litigation progress, risk notes, deadlines, and communications with outside counsel, but it provides no privacy warning, minimization guidance, access controls, retention limits, or handling constraints. In the context of legal operations, this increases the risk of exposing privileged, confidential, or regulated data and could lead to confidentiality breaches or improper downstream AI processing.
This markdown file contains all user-facing guidance in Chinese, including the title, instructions, and examples, with no indication that users can select another language. The policy requires flagging language or locale constraints when a skill forces a specific language without user opt-in or explicit justification.
The file presents all instructions, criteria, and keywords exclusively in Chinese, which can amount to a forced language/locale choice if the broader skill environment serves multilingual users. There is no natural-language statement offering alternative languages or documenting that the skill is intentionally limited to Chinese-speaking sales workflows.
The module description and command/help text are written in Chinese, and later user-visible messages are also emitted in Chinese. There is no indication that users can choose another language or that the skill is intentionally limited to a Chinese-speaking or region-specific context.
The post() helper sends user_id, amount, and skill_id to an external service, enabling charge and payment-link creation. The script contains no confirmation prompt or explicit warning to users that their billing data will be transmitted to a third-party endpoint.
The skill fetches raw Feishu group messages and returns message text, sender identifiers, and timestamps for downstream AI analysis without any consent check, minimization, or warning at this boundary. In the context of a group-memory skill, this can expose sensitive internal discussions, customer data, or legal/project information to users or downstream systems beyond the expectations of all chat participants.
This code performs a file write to a fixed context file path and will overwrite existing contents if the file already exists. Although the module docstring mentions file read/write, there is no user-facing warning or confirmation in this command about replacing prior workspace data.
This code file contains natural-language strings and documentation that force a specific language for usage instructions and output messaging. Under the policy, a skill should not impose a language or locale without user opt-in or a clearly documented region-specific justification.
The script returns Chinese-only user-facing messages such as "暂无记录" and later "请指定命令". This is a natural-language locale constraint in operational output, and the file does not offer any language selection or explain why Chinese is required.
The command-line error message is presented only in Chinese, which can exclude users who did not opt into that locale. The policy allows locale constraints only when user choice is offered or the restriction is clearly justified, neither of which is present here.
The template explicitly asks authors to provide 20–30 trigger keywords but does not require narrow scoping, disambiguation, or exclusion terms. In a skill that ingests group chat and stores structured memory, broad keywords can cause over-collection and unintended activation on unrelated or sensitive conversations, degrading privacy and increasing the chance of retaining irrelevant data.
These lines direct the model to take free-form user input, transform it into a knowledge pack, and save it for later sessions. That creates a semantic data-retention instruction in natural language, with risk that sensitive operational details from the user's description are stored and reused beyond the immediate interaction.