Back to skill

Security audit

Blockchain Balance Checker

Security checks for vulnerabilities and agentic risk

Overview

The skill does the advertised blockchain balance lookup, but it may expose the Tokenview API key in error output and can send wallet addresses to Tokenview under a broad trigger.

Review before installing. Use only with a Tokenview API key you are comfortable exposing to this skill process, and prefer fixing the error handler to redact apikey before use. Users should also understand that queried wallet addresses and coin types are sent to Tokenview and should invoke the skill only for explicit balance-check requests.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Warning
Location
tokenview_api.py:62
Finding

Tokenview API Key Disclosure Through Unsanitized Network Errors

Content
View full analysis

Vulnerability Details

File Location: tokenview_api.py, lines 62–80
Vulnerability Type: API credential exposure through query-string construction and unsanitized exception output
Risk Level: Medium

Vulnerable Code

python
url = f"{BASE_URL}/{coin}/{address}?apikey={api_key}"
try:
    resp = requests.get(url, timeout=10)
    resp.raise_for_status()
python
except requests.exceptions.RequestException as e:
    print(json.dumps({"code": -3, "msg": f"Network error: {e}", "data": "NONE"}))
    sys.exit(1)

Technical Analysis

The Tokenview API key is embedded directly in the request URL as the apikey query parameter. URLs are commonly included in HTTP client exceptions, diagnostic output, proxy logs, monitoring systems, and request histories.

In particular, requests.Response.raise_for_status() can raise an HTTPError whose string representation contains the complete request URL. The handler catches that exception and copies its unsanitized string representation directly into JSON printed to standard output. Consequently, the value of TOKENVIEW_API_KEY may be returned to the invoking agent, displayed to a user, or retained in execution and conversation logs.

Sending the API key and requested blockchain address to the documented Tokenview HTTPS endpoint is consistent with the Skill's declared balance-query functionality. The security issue is not the required network request itself, but the unnecessary propagation of a secret-bearing URL into externally visible error output.

Attack Path

  1. The Skill obtains TOKENVIEW_API_KEY from the environment.
  2. It constructs a URL containing the credential in the query string.
  3. A submitted query or a Tokenview-side condition results in a non-success HTTP status.
  4. resp.raise_for_status() raises a requests.exceptions.HTTPError.
  5. The exception string can contain the full URL, including ?apikey=....
  6. The exception ...[truncated 844 chars]
Remediation
View remediation

Remediation Suggestions

  1. Do not return raw requests exception text to users or agent-visible output. Replace it with a fixed message and, where useful, a non-sensitive HTTP status code.
  2. If Tokenview supports an authorization header, transmit the API key in that header rather than in the URL.
  3. If the API contract requires a query parameter, redact apikey from every URL before logging or displaying it.
  4. Separate internal diagnostics from user-facing errors. Internal logs should also apply structured secret redaction and restrictive access controls.
  5. Avoid logging response request objects, prepared URLs, or tracebacks unless a redaction filter is active.
  6. Rotate the current Tokenview API key if the vulnerable implementation has already been used and its output may have been retained.

A hardened error handler could use the following pattern:

python
except requests.exceptions.HTTPError as e:
    status = e.response.status_code if e.response is not None else "unknown"
    print(json.dumps({
        "code": -3,
        "msg": f"Tokenview request failed with HTTP status {status}",
        "data": "NONE"
    }))
    sys.exit(1)
except requests.exceptions.RequestException:
    print(json.dumps({
        "code": -3,
        "msg": "Tokenview network request failed",
        "data": "NONE"
    }))
    sys.exit(1)
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (6)

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

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · tokenview_api.py (reported line 69)May include surrounding context.

python
url = f"{BASE_URL}/{coin}/{address}?apikey={api_key}"  # e.g. https://services.tokenview.io/vipapi/addr/b/eth/0x... 
    try:
        resp = requests.get(url, timeout=10)
        resp.raise_for_status()
        data = resp.json()
        # 成功格式

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill documentation does not warn users that supplied blockchain addresses are transmitted to Tokenview, a third-party service. Even though blockchain addresses are public identifiers in many contexts, associating a user's queried address with their conversation or account can leak privacy-sensitive information and create compliance concerns.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger is broad enough that any conversation containing something that looks like a blockchain address may invoke the skill, even when the user did not clearly consent to an external balance lookup. Because invocation sends the address to a third-party API, this can cause unintended disclosure of potentially sensitive financial metadata and unexpected tool execution.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The inline documentation states the function returns a string and uses exceptions for unsupported chain or request errors. In practice, the function primarily performs side effects by printing JSON output, and on missing API key, missing address, or request/parsing failures it calls sys.exit(1) rather than raising ValueError. This is an active contradiction in documented behavior versus implementation intent.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This code constructs and sends an HTTP request to the Tokenview API containing the wallet address and API key, which is a transmission of user/system data to an external service. While the module docstring says it fetches balances from Tokenview, there is no explicit user-facing warning, confirmation, or privacy disclosure near the request about sending the queried address and credentials off-host.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

The code emits a hard-coded Chinese success message ("成功") in its natural-language output and logic, with no option for the user to choose locale or language. This can violate language/locale policy expectations because the skill imposes a specific language rather than offering user choice or documenting a justified locale constraint.

Content

No source excerpt is available for this finding.