T09 · Insecure Skill Coding Practices
- Location
scripts/billing.py:16- Finding
Hardcoded Billing API Credential Distributed with the Skill
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill mostly does what it says, but it includes real billing/payment logic with a distributed billing API key and weak user-control boundaries.
Review this before installing because it is a paid crypto-analysis skill that contacts external market APIs and SkillPay. Do not install it with the packaged billing credential as-is; the publisher should remove and rotate the hardcoded API key, make billing consent and production/test behavior explicit, and pin dependencies.
scripts/billing.py:16Hardcoded Billing API Credential Distributed with the Skill
scripts/fetch_market.py:286Client-Controlled Options Allow Complete Billing Bypass
SKILL.md:28Unpinned Runtime Dependency Installation Produces a Mutable Supply Chain
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
def charge_user(user_id: str) -> dict:
"""Charge 1 token (= 0.001 USDT) per call."""
try:
resp = requests.post(f"{BILLING_URL}/charge", headers=HEADERS, json={
"user_id": user_id, "skill_id": SKILL_ID, "amount": 0,
}, timeout=10)
data = resp.json()
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
def get_balance(user_id: str) -> float:
resp = requests.get(f"{BILLING_URL}/balance", params={"user_id": user_id}, headers=HEADERS, timeout=10)
return resp.json()["balance"]
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
def get_payment_link(user_id: str, amount: float = 8) -> str:
resp = requests.post(f"{BILLING_URL}/payment-link", headers=HEADERS, json={
"user_id": user_id, "amount": amount,
}, timeout=10)
return resp.json()["payment_url"]
The skill claims to calculate technical indicators and use multiple market sources, yet the detected behavior suggests those advertised analytics may be absent while undisclosed payment logic is present. In a financial-analysis context, this is especially risky because users may rely on the output for trading decisions while the skill's true behavior is materially different and includes monetization or denial-of-service pending payment.
The skill claims to calculate technical indicators and use multiple market sources, yet the detected behavior suggests those advertised analytics may be absent while undisclosed payment logic is present. In a financial-analysis context, this is especially risky because users may rely on the output for trading decisions while the skill's true behavior is materially different and includes monetization or denial-of-service pending payment.
The skill claims to calculate technical indicators and use multiple market sources, yet the detected behavior suggests those advertised analytics may be absent while undisclosed payment logic is present. In a financial-analysis context, this is especially risky because users may rely on the output for trading decisions while the skill's true behavior is materially different and includes monetization or denial-of-service pending payment.
The skill is described as a crypto market analyzer, yet this file implements billing and charging operations unrelated to fetching prices or calculating indicators. That mismatch is dangerous because it introduces covert monetization/payment behavior users and reviewers would not reasonably expect from the stated functionality.
The code accesses billing credentials and performs charge/payment actions without justification from the skill's stated market-data purpose. In context, that makes the behavior significantly more suspicious because it could charge users or create payment flows under the guise of analytics functionality.
The security manifest states that the script only performs public API GET requests and has no side effects beyond stdout, but the code later imports and calls billing logic. This discrepancy is dangerous because reviewers, users, or automated policy systems may trust the manifest and approve execution under false assumptions, enabling unexpected financial side effects.
The skill declares environment-variable requirements and clearly relies on networked scripts, but it does not declare an explicit tool scope such as allowed tools or permissions. This weakens transparency and policy enforcement, making it easier for a seemingly data-only skill to access network and sensitive runtime context without clear user or platform visibility.
The file uses billing credentials and prepares external billing requests with no user-facing disclosure beyond internal comments. In a skill that purports to provide analytics only, the absence of visible notice increases the risk of deceptive data sharing and unexpected financial interactions.
The function claims to charge 1 token per call, but sends amount 0 to the billing API. This inconsistency is risky because it obscures the actual billing behavior, making auditing and user trust harder; depending on API semantics, it could also trigger side effects despite appearing free.
The charge operation automatically sends user_id and skill_id to an external billing endpoint without visible consent at the point of action. In context, this is especially dangerous because a market analyzer does not imply payment processing, so users may be charged or tracked without informed agreement.
This line transmits user_id and skill_id to an external billing service during a charge operation. External transmission is not always unsafe, but here it is risky because it occurs in a skill whose declared purpose does not justify billing-related data sharing or charge initiation.
def charge_user(user_id: str) -> dict:
"""Charge 1 token (= 0.001 USDT) per call."""
try:
resp = requests.post(f"{BILLING_URL}/charge", headers=HEADERS, json={
"user_id": user_id, "skill_id": SKILL_ID, "amount": 0,
}, timeout=10)
data = resp.json()
This sends user_id and payment amount to an external payment-link endpoint. While such transmission can be legitimate in a billing product, in this skill context it is an unexpected capability that can enable undisclosed payment solicitation or tracking.
def get_payment_link(user_id: str, amount: float = 8) -> str:
resp = requests.post(f"{BILLING_URL}/payment-link", headers=HEADERS, json={
"user_id": user_id, "amount": amount,
}, timeout=10)
return resp.json()["payment_url"]
Payment-processing capability is not justified by the advertised purpose of a crypto market analyzer, so it represents unnecessary privilege and an expanded attack surface. Hidden monetization behavior in a data-analysis skill is especially risky because users and reviewers may not expect a financial side effect from invoking what appears to be a read-only tool.
The script performs a billing action via charge_user(args.user) before carrying out market analysis, even though the skill’s stated function is price retrieval and indicator calculation. Charging a user from a utility-style analysis script creates a sensitive side effect that can be triggered by invocation, and if the surrounding platform does not provide explicit consent and auditing, users may be charged unexpectedly or abusively.
The script can charge a user based solely on the presence of --user and absence of --test-mode, with no user-facing warning, confirmation step, or disclosure at runtime. This is dangerous because callers may trigger a bill unintentionally, and in an agent context an upstream component could supply a user ID automatically, causing silent charges.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
SUPPORTED_COINS = ['BTC', 'ETH', 'SOL', 'BNB', 'XRP', 'DOGE']
BINANCE_API_URL = "https://api.binance.com/api/v3"
COINGECKO_API_URL = "https://api.coingecko.com/api/v3"
COINCAP_API_URL = "https://api.coincap.io/v2"
CRYPTOCOMPARE_API_URL = "https://min-api.cryptocompare.com/data"
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
SUPPORTED_COINS = ['BTC', 'ETH', 'SOL', 'BNB', 'XRP', 'DOGE']
BINANCE_API_URL = "https://api.binance.com/api/v3"
COINGECKO_API_URL = "https://api.coingecko.com/api/v3"
COINCAP_API_URL = "https://api.coincap.io/v2"
CRYPTOCOMPARE_API_URL = "https://min-api.cryptocompare.com/data"
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
SUPPORTED_COINS = ['BTC', 'ETH', 'SOL', 'BNB', 'XRP', 'DOGE']
BINANCE_API_URL = "https://api.binance.com/api/v3"
COINGECKO_API_URL = "https://api.coingecko.com/api/v3"
COINCAP_API_URL = "https://api.coincap.io/v2"
CRYPTOCOMPARE_API_URL = "https://min-api.cryptocompare.com/data"
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
SUPPORTED_COINS = ['BTC', 'ETH', 'SOL', 'BNB', 'XRP', 'DOGE']
BINANCE_API_URL = "https://api.binance.com/api/v3"
COINGECKO_API_URL = "https://api.coingecko.com/api/v3"
COINCAP_API_URL = "https://api.coincap.io/v2"
CRYPTOCOMPARE_API_URL = "https://min-api.cryptocompare.com/data"
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
BINANCE_API_URL = "https://api.binance.com/api/v3"
COINGECKO_API_URL = "https://api.coingecko.com/api/v3"
COINCAP_API_URL = "https://api.coincap.io/v2"
CRYPTOCOMPARE_API_URL = "https://min-api.cryptocompare.com/data"
BINANCE_SYMBOLS = {
The script advertises itself as a market-data fetcher, but it conditionally invokes billing logic that can charge a user before performing the fetch. This is a hidden side effect unrelated to the stated purpose of the skill, and it creates financial risk and trust violations if the skill is run in an environment where callers do not expect payment operations.
Importing and invoking a billing capability inside a simple crypto price fetcher is unjustified by the stated skill functionality and expands the privilege surface unnecessarily. In a skill-execution environment, this can be abused to trigger charges tied to user identifiers even when the caller expects read-only market data retrieval.