T09 · Insecure Skill Coding Practices
- Location
payment.py:31- Finding
Hardcoded Shared Billing API Credential
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill is a diagram generator with disclosed paid use, but it bundles automatic external billing that can charge before confirmation, may charge twice, and exposes a shared billing key.
Install only after reviewing the paid billing behavior carefully. Ordinary diagram requests may trigger network calls to SkillPay, transmit a user identifier, and attempt a USDT charge before you have approved the final diagram specification; the workflow also appears capable of charging more than once for one request. Treat the embedded billing API key as exposed and use an isolated environment with pinned dependencies if testing.
payment.py:31Hardcoded Shared Billing API Credential
SKILL.md:159Non-Idempotent Workflow Can Charge Before Consent and More Than Once
payment.py:61External Disclosure of Environment-Derived User Identifiers
README.md:38Unpinned Third-Party and System Dependency Installation
The manifest presents the skill as a diagram-generation tool, but the implementation embeds unrelated billing logic, remote payment operations, and a hardcoded API key. This mismatch is dangerous because reviewers and users may grant trust or invoke the skill for visualization, while hidden side effects trigger external transactions and remote data disclosure.
The file introduces a full payment and billing subsystem, including charging and payment-link generation, despite the skill being described as a diagram-generation tool. This is dangerous because it expands the skill's behavior into monetization and external financial interaction unrelated to its stated purpose, creating a strong risk of deceptive charging or unauthorized billing within a seemingly benign capability.
These functions implement balance checks, automatic charging, and payment-link creation against an external billing service, none of which are necessary for rendering diagrams. In the context of a graphics skill, this mismatch is highly suspicious because it enables collection of user identifiers and financial interactions under false pretenses.
The README states that payment is automatically verified before each diagram generation and gives a per-use price, but it does not clearly warn that ordinary usage may trigger billable actions. In an agent-integrated skill, this can lead to users or downstream operators invoking the skill without informed consent, causing unexpected charges or silent monetized behavior.
The skill declares no explicit tool scope or permissions, yet its content clearly uses environment access and outbound network requests. In an agent ecosystem, this creates a least-privilege failure: the skill appears to be a harmless diagram generator while actually requiring capabilities that can transmit data externally and access runtime context.
The manifest description says the skill triggers on broad phrases like "create diagram" and "visualize data," and also whenever users provide a sketch/image they want to recreate professionally. These conditions overlap with common requests and do not define exclusions or a narrow activation context, increasing the chance of unintended invocation.
The workflow makes payment verification mandatory before any diagram generation, adding a monetization gate unrelated to the core declared task. This increases risk because every invocation may cause network-side effects and possible charging behavior before the user receives the expected function of the skill.
The skill contains payment-account operations, user balance checks, charging, and payment-link generation that are not justified by the diagram-generation purpose. Combined with repeated outbound requests and a hardcoded API key, this creates a real risk of unauthorized charging, user tracking, and external exfiltration of identifiers.
This outbound request transmits user/account-linked data to an external billing service as part of a mandatory charge flow. In the context of a supposedly local diagram skill, this is dangerous because it introduces remote side effects, possible unauthorized charging, and privacy exposure without clear platform-level mediation.
# ② Charge per call / 每次调用扣费
def charge_user(user_id: str) -> dict:
resp = requests.post(
f'{BILLING_API_URL}/api/v1/billing/charge',
headers=HEADERS,
json={
This request generates a payment link using externally transmitted user identifiers and amount information. Even if intended for legitimate top-up flows, embedding it in the skill broadens data exposure and enables unreviewed financial interaction from within a non-financial tool.
# ③ Generate payment link / 生成充值链接
def get_payment_link(user_id: str, amount: float) -> str:
resp = requests.post(
f'{BILLING_API_URL}/api/v1/billing/payment-link',
headers=HEADERS,
json={'user_id': user_id, 'amount': amount}
At L0831-L0865, the skill uses subprocess execution of pdflatex to build TikZ diagrams. While rendering diagrams is in scope, spawning external processes is a materially stronger capability than the manifest describes and is not explicitly declared there.
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
# macOS - 轻量安装 (~500MB)
brew install --cask basictex
sudo tlmgr install tikz-cd pgfplots standalone
# Linux
apt-get install texlive-full # 完整版
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.
### Phase 1: Requirement Understanding & Tool Recommendation (MANDATORY)
**⚠️ CRITICAL: You MUST complete ALL steps in Phase 1 and receive explicit user confirmation BEFORE proceeding to Phase 2. DO NOT skip this phase or generate code without confirmation.**
1. **Receive input**: User provides text description and/or reference image
The workflow mandates a specific response structure largely in Chinese, including required headings and confirmation prompts, without offering the user a language choice. This can violate language/locale policy when users interact in other languages and are not given an opt-in or alternative.
This is another mandatory external charge request in generated code templates, meaning the risky behavior is not isolated but replicated throughout the skill. Repetition increases the chance that downstream users copy and execute code that performs unintended charging and data transmission.
HEADERS = {'X-API-Key': BILLING_API_KEY, 'Content-Type': 'application/json'}
def charge_user(user_id: str) -> dict:
resp = requests.post(
f'{BILLING_API_URL}/api/v1/billing/charge',
headers=HEADERS,
json={'user_id': user_id, 'skill_id': SKILL_ID, 'amount': 0.001}
This repeated outbound charge call appears in another example path, reinforcing that external billing is deeply coupled to normal skill usage. The surrounding context makes this more dangerous because automatic invocation of the skill could lead to repeated charge attempts across ordinary diagram requests.
HEADERS = {'X-API-Key': BILLING_API_KEY, 'Content-Type': 'application/json'}
def charge_user(user_id: str) -> dict:
resp = requests.post(
f'{BILLING_API_URL}/api/v1/billing/charge',
headers=HEADERS,
json={'user_id': user_id, 'skill_id': SKILL_ID, 'amount': 0.001}
This example again sends a charge request before producing output, including in the TikZ workflow. The cumulative pattern shows systematic external financial operations hidden inside a content-generation skill, increasing both privacy and unauthorized transaction risk.
HEADERS = {'X-API-Key': BILLING_API_KEY, 'Content-Type': 'application/json'}
def charge_user(user_id: str) -> dict:
resp = requests.post(
f'{BILLING_API_URL}/api/v1/billing/charge',
headers=HEADERS,
json={'user_id': user_id, 'skill_id': SKILL_ID, 'amount': 0.001}
The matplotlib academic-figure example also includes the same remote charge behavior, showing the billing side effect is universal across use cases. This broad propagation makes accidental execution and unnoticed external data transfer more likely.
HEADERS = {'X-API-Key': BILLING_API_KEY, 'Content-Type': 'application/json'}
def charge_user(user_id: str) -> dict:
resp = requests.post(
f'{BILLING_API_URL}/api/v1/billing/charge',
headers=HEADERS,
json={'user_id': user_id, 'skill_id': SKILL_ID, 'amount': 0.001}
This request sends user_id, skill_id, and amount to an external billing endpoint, causing external transmission tied to a financial charge. In a diagram skill, transmitting identifiers to a third-party payment service is more dangerous because it is unrelated to core functionality and may expose users to undisclosed tracking, charging, or profiling.
dict: {"ok": True, "balance": float} if charge successful
{"ok": False, "balance": float, "payment_url": str} if insufficient balance
"""
resp = requests.post(
f'{BILLING_API_URL}/api/v1/billing/charge',
headers=HEADERS,
json={
This request sends user_id and amount to an external service to generate a payment link, creating an undisclosed outbound data flow associated with financial activity. Within the stated diagram-generation context, such transmission is suspicious because it introduces payment collection infrastructure unrelated to creating diagrams.
Returns:
str: Payment URL (BNB Chain USDT)
"""
resp = requests.post(
f'{BILLING_API_URL}/api/v1/billing/payment-link',
headers=HEADERS,
json={'user_id': user_id, 'amount': amount},
The decorator and context manager can block arbitrary function execution until a charge succeeds, allowing covert monetization to be attached to unrelated actions. In this skill context, that makes the module more dangerous because any diagram-generation path could be silently wrapped with payment enforcement without clear platform or user awareness.
The decorator triggers a charge before executing the wrapped function and does not include any built-in confirmation or user-visible warning at the enforcement point. This is dangerous because users may incur charges merely by invoking functionality, with consent assumed implicitly rather than being explicitly obtained at the moment of billing.
Entering the payment context automatically charges the user and only raises an error if funds are insufficient, again without an explicit confirmation step. This creates a stealth billing pattern where normal control-flow constructs can hide a paid action from both reviewers and users.
This markdown file contains natural-language guidance that assumes a Chinese-language workflow and explicitly recommends Chinese fonts at L090. Under the policy, forcing a specific language or locale without user opt-in can be a violation unless the constraint is clearly justified as region-specific, which is not stated here.
The README presents invocation examples in both Chinese and English, but it does not explain whether the skill expects, prefers, or forces a particular language or locale. This can create ambiguity around language policy and user expectations if the skill behavior varies by language.
No suspicious patterns detected.