Back to skill

Security audit

Crypto Market Analyzer

Security checks for vulnerabilities and agentic risk

Overview

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.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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 (3)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/billing.py:16
Finding
Hardcoded Billing API Credential Distributed with the Skill<![CDATA[ ## Vulnerability Details **File Location**: `scripts/billing.py`, lines 16-19 **Vulnerability Type**: Hardcoded secret and insecure credential management **Risk Level**: High ### Vulnerable Code ```python BILLING_URL = "https://skillpay.me/api/v1/billing" API_KEY = os.environ.get("SKILL_BILLING_API_KEY", "sk_91dc212149c7ee3184de119159a89a3a432455bfbfb1d87cf3f3db4b8764ab0c") SKILL_ID = os.environ.get("SKILL_ID", "paythefly") HEADERS = {"X-API-Key": API_KEY, "Content-Type": "application/json"} ``` ### Technical Analysis The billing API credential is embedded directly in the distributed source code as the default value of `SKILL_BILLING_API_KEY`. Supplying an environment variable does not mitigate the exposure because every recipient of the package can inspect and extract the fallback credential. The credential is placed in the `X-API-Key` header used by the charge, balance, and payment-link endpoints. Although the code comments characterize it as a publisher-side, charge-only key, its actual permissions depend on server-side authorization and cannot be verified statically. At minimum, the key allows an external party to impersonate the Skill when making whatever billing requests the server permits. ### Attack Path 1. An attacker downloads or otherwise obtains the Skill package. 2. The attacker opens `scripts/billing.py` and extracts the embedded API key and default Skill ID. 3. The attacker sends requests directly to endpoints below `https://skillpay.me/api/v1/billing`, placing the extracted value in the `X-API-Key` header. 4. The attacker attempts charge, balance, or payment-link operations using chosen user identifiers. 5. Any operation permitted by the server-side scope of the exposed key executes as the publisher identity. No local code execution or system privilege escalation is needed to exploit the exposure. ### Impact Assessment The immediate impact is compromise of the billing credential and loss of publisher identity integrity. Depend ...[truncated 413 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Immediately revoke and rotate the exposed API key. 2. Remove the hardcoded fallback and require `SKILL_BILLING_API_KEY` to be supplied through a protected secret store. 3. Fail closed when the credential is absent: ```python API_KEY = os.environ.get("SKILL_BILLING_API_KEY") if not API_KEY: raise RuntimeError("SKILL_BILLING_API_KEY is required") ``` 4. Do not distribute publisher credentials in client-controlled Skill packages. Proxy billing through a trusted backend when practical. 5. Restrict the replacement credential to the minimum necessary endpoint, Skill ID, operation, amount, and rate. 6. Enforce user and Skill authorization server-side rather than trusting caller-provided identifiers. 7. Add key rotation, abuse monitoring, rate limiting, and alerts for unusual billing requests. 8. Review billing logs for use of the exposed key and invalidate any related sessions or derived credentials. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/fetch_market.py:286
Finding
Client-Controlled Options Allow Complete Billing Bypass<![CDATA[ ## Vulnerability Details **File Locations**: - `scripts/fetch_market.py`, lines 286-294 - `scripts/calc_indicators.py`, lines 402-410 **Vulnerability Type**: Billing and access-control bypass **Risk Level**: Medium ### Vulnerable Code `scripts/fetch_market.py`: ```python parser.add_argument("--user", type=str, default="", help="User ID for billing") parser.add_argument("--test-mode", action="store_true", help="Skip billing for testing") args = parser.parse_args() # Billing check (skip in test mode) if args.user and not args.test_mode: from billing import charge_user billing_result = charge_user(args.user) ``` `scripts/calc_indicators.py`: ```python parser.add_argument("--user", type=str, default="", help="User ID for billing") parser.add_argument("--test-mode", action="store_true", help="Skip billing for testing") args = parser.parse_args() # Billing check if args.user and not args.test_mode: from billing import charge_user billing_result = charge_user(args.user) ``` ### Technical Analysis Billing is enforced only when a nonempty `--user` value is supplied and `--test-mode` is absent. Both conditions are fully controlled by the local caller. The parser assigns an empty default to `--user`, despite `SKILL.md` describing that argument as required. Consequently, omitting `--user` skips the billing branch. A caller can also explicitly pass `--test-mode` to bypass billing. Neither path is restricted to a development environment or authorized tester. This is a business-logic and access-control weakness rather than an operating-system privilege escalation. Because enforcement occurs entirely in locally distributed code, a caller can also modify the code even if the command-line bypasses are removed. ### Attack Path 1. The caller invokes either script without the `--user` argument, for example: ```bash python scripts/fetch_market.py --coins BTC,ETH python scripts/calc_indicators.py --coin BTC ``` 2. Because `args.user` is an em ...[truncated 777 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Make `--user` mandatory when billing is enabled: ```python parser.add_argument("--user", required=True, help="User ID for billing") ``` 2. Remove `--test-mode` from production distributions or require a server-issued, short-lived authorization token that cannot be generated by ordinary callers. 3. Fail closed when billing is unavailable, returns malformed data, or does not explicitly confirm a successful charge. 4. Validate that the billed user is authorized to invoke the Skill; do not rely only on a caller-supplied user ID. 5. Move access enforcement and paid execution to a trusted service. Local client-side code cannot reliably enforce payment against a caller who controls the runtime and source. 6. Separate test and production builds so testing bypasses cannot be enabled in the production package. 7. Add automated tests confirming that missing users, test flags, billing failures, and malformed billing responses cannot reach paid functionality in production. ]]>

T08 · Insecure Dependencies

Note
Location
SKILL.md:28
Finding
Unpinned Runtime Dependency Installation Produces a Mutable Supply Chain<![CDATA[ ## Vulnerability Details **File Locations**: - `SKILL.md`, lines 28-34 - `README.md`, lines 38-41 **Vulnerability Type**: Unpinned third-party dependency **Risk Level**: Low ### Vulnerable Code `SKILL.md`: ```markdown ## Dependencies The scripts require the `requests` Python library. Install it if not available: ```bash pip install requests ``` ``` `README.md`: ```markdown ## Requirements - Python 3.9+ - `requests` library (`pip install requests`) ``` ### Technical Analysis The installation instructions resolve `requests` and its transitive dependencies at installation time without a pinned version, lock file, or integrity hashes. As a result, two installations performed at different times may execute different dependency versions. The package name is legitimate and the audit found no evidence of typosquatting or an intentionally malicious dependency. The risk arises from mutable dependency resolution: a compromised package-index account, malicious release, unsafe index configuration, or incompatible future version could introduce code that executes when the Skill imports `requests`. ### Attack Path A viable exploitation path requires compromise or manipulation of the dependency supply chain: 1. A user follows the documented `pip install requests` instruction. 2. `pip` resolves the current package and transitive dependencies from its configured index. 3. If that index, package release, maintainer account, or local index configuration has been compromised, the installer downloads attacker-controlled code. 4. Installation hooks or subsequently imported package code execute with the privileges of the user running the installation or Skill. 5. The malicious dependency can access data and resources available to that process. The project itself does not retrieve or execute a remote source-code payload; exploitation is conditional on dependency or package-index compromise. ### Impact Assessment A compromised dependency could execute Python co ...[truncated 378 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Add a reviewed dependency file with an exact version, for example: ```text requests==<reviewed-version> ``` 2. Pin all transitive dependencies using a lock-generation tool rather than relying only on a top-level version. 3. Record cryptographic hashes and install with hash verification: ```bash python -m pip install --require-hashes -r requirements.txt ``` 4. Use an approved package index and prevent unexpected dependency resolution from untrusted additional indexes. 5. Install dependencies inside an isolated virtual environment with minimum user privileges. 6. Add automated dependency vulnerability scanning and a controlled process for reviewing and updating pinned versions. 7. Update both `SKILL.md` and `README.md` to direct users to the locked, hash-verified installation procedure. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (25)

Tainted flow: 'HEADERS' from os.environ.get (line 19, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
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()
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'HEADERS' from os.environ.get (line 19, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Content
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"]
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'HEADERS' from os.environ.get (line 19, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
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"]
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
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.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
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.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
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.

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
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.

Context-Inappropriate Capability

High
Confidence
99% confidence
Finding
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.

Intent-Code Divergence

High
Confidence
99% confidence
Finding
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.

Lp3

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding
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.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
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.

Intent-Code Divergence

Medium
Confidence
95% confidence
Finding
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.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
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.

External Transmission

Medium
Category
Data Exfiltration
Content
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()
Confidence
89% confidence
Finding
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.

External Transmission

Medium
Category
Data Exfiltration
Content
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"]
Confidence
84% confidence
Finding
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.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
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.

Description-Behavior Mismatch

Medium
Confidence
97% confidence
Finding
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.

Missing User Warnings

Medium
Confidence
98% confidence
Finding
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.

External Transmission

Medium
Category
Data Exfiltration
Content
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"
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
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"
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
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"
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
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"
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
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 = {
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Description-Behavior Mismatch

Medium
Confidence
97% confidence
Finding
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.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
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.

Static analysis

No suspicious patterns detected.