Back to skill

Security audit

Helius x Phantom

Security checks for vulnerabilities and agentic risk

Overview

The skill is coherent and not malicious, but it should be reviewed because it combines payment-capable crypto workflows, persisted credentials, mutable package installs, and some under-scoped security examples.

Review before installing. Pin the MCP and starter package versions instead of using `@latest`, keep Helius API keys and JWTs in restricted secret storage, and require explicit user confirmation before signup, upgrades, renewals, wallet auto-confirm, or any transaction that spends funds. Treat the included proxy, payment verification, token-gating, and SSE examples as starting points only; harden them with authentication, allowlists, schema validation, durable rate limits, nonce-based signing, exact payment verification, replay protection, and clear user-facing disclosure.

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

T08 · Insecure Dependencies

Warning
Location
references/helius-onboarding.md:188
Finding
Mutable MCP Dependency Is Downloaded and Executed Without Version Pinning<![CDATA[ ## Vulnerability Details **File Location**: `references/helius-onboarding.md:188-190` **Additional Locations**: `SKILL.md:24-25`, `SKILL.md:335`, `install.sh:68-69` **Vulnerability Type**: Unpinned third-party executable dependency **Risk Level**: Medium ### Vulnerable Code ```bash ### Installing the MCP ```bash claude mcp add helius npx helius-mcp@latest ``` ``` The installer repeats the same instruction: ```bash echo " 1. Install the Helius MCP server (if not already):" echo " claude mcp add helius npx helius-mcp@latest" ``` ### Technical Analysis The command invokes `npx` with the mutable `latest` package tag. This downloads and executes whichever `helius-mcp` release the registry currently associates with that tag. Consequently, the code executed by users may differ from the version that existed when this Skill was reviewed. No exact package version, lockfile, package integrity hash, or other reproducibility control is specified. Because the MCP server is expected to handle API keys, persisted authentication state, keypairs, and blockchain transactions, compromise of its package or publisher account would expose security-sensitive capabilities. This is a supply-chain risk rather than evidence that the current package is malicious. ### Attack Path 1. An attacker compromises the `helius-mcp` publisher account, package registry entry, or release process. 2. The attacker publishes a malicious version and assigns it the `latest` tag. 3. A user follows the Skill's setup instructions. 4. `npx helius-mcp@latest` retrieves and executes the attacker's mutable package. 5. The package runs with the user's permissions and can access resources available to the MCP process. ### Impact Assessment A compromised dependency could potentially access Helius API credentials, persisted JWTs, Solana signup keypairs, project data, and other files readable by the user. It could also falsify MCP tool responses or initiate unauthorized network activity. Th ...[truncated 87 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace `@latest` with an exact, reviewed version: ```bash claude mcp add helius npx helius-mcp@1.2.3 ``` 2. Use a lockfile and verify package integrity where the installation mechanism supports it. 3. Document the expected package publisher, version, and release checksum. 4. Review upgrades before changing the pinned version. 5. Run the MCP server with the minimum filesystem and network permissions required. 6. Keep payment, key-generation, and account-upgrade operations behind explicit user confirmation. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
references/payments.md:289
Finding
Payment Confirmation Accepts an Unrelated Successful Transaction<![CDATA[ ## Vulnerability Details **File Location**: `references/payments.md:289-315` **Vulnerability Type**: Incomplete server-side payment verification **Risk Level**: Critical ### Vulnerable Code ```ts // app/api/payments/confirm/route.ts export async function POST(req: Request) { const { paymentId, txHash } = await req.json(); // Verify transaction on-chain using Helius Enhanced Transactions API // See references/helius-enhanced-transactions.md const txRes = await fetch(`https://api.helius.xyz/v0/transactions?api-key=${HELIUS_API_KEY}`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ transactions: [txHash] }), }); const [parsed] = await txRes.json(); if (!parsed || parsed.transactionError) { return Response.json({ success: false }); } // Verify amount and recipient match expected values // Update payment status // Fulfill order return Response.json({ success: true }); } ``` ### Technical Analysis The endpoint only establishes that the client-supplied transaction hash refers to a parsed transaction without a reported transaction error. The security-critical verification steps are comments and are not implemented. The endpoint does not load the referenced payment record or verify: - The expected merchant recipient - The exact SOL amount or token amount - The expected token mint - The payer associated with the order - A payment reference or order identifier - The required confirmation or finalization status - Transaction freshness or payment expiration - Whether the transaction was already used for another payment - Whether the payment or order was previously fulfilled The untrusted client supplies both `paymentId` and `txHash`. A successful unrelated transaction can therefore satisfy the implemented condition. ### Attack Path 1. The attacker creates or identifies an unpaid order and obtains a `paymentId`. 2. The attacker obtains the hash of any successful Solana tra ...[truncated 879 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Load the payment and order records using `paymentId`; reject missing, expired, cancelled, or already fulfilled records. 2. Validate and normalize `txHash` before querying Helius. 3. Require the expected confirmation level before fulfillment. 4. Parse transfers and verify the exact recipient, asset mint, and amount against server-maintained payment data. 5. Bind the transaction to the order using a unique reference, memo, or server-generated transaction. 6. Verify the expected payer when the business flow requires it. 7. Store the transaction signature under a unique database constraint so it cannot satisfy multiple payments. 8. Atomically transition the payment from `pending` to `paid` and create the fulfillment record in one database transaction. 9. Make fulfillment idempotent and return success for an already completed payment without performing it again. 10. Reject stale transactions and enforce the payment request's server-side expiration. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
references/token-gating.md:87
Finding
Client-Controlled Future Timestamp Enables Indefinite Authentication Replay<![CDATA[ ## Vulnerability Details **File Location**: `references/token-gating.md:87-168` **Vulnerability Type**: Replayable wallet-signature authentication **Risk Level**: High ### Vulnerable Code ```tsx async function verifyAccess(solana: any) { const address = await solana.getPublicKey(); const timestamp = Date.now(); const message = `Verify ownership\nAddress: ${address}\nTimestamp: ${timestamp}`; const { signature } = await solana.signMessage(message); const res = await fetch("/api/verify-access", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ address, signature, message, timestamp }), }); return await res.json(); } ``` ```ts export async function POST(req: Request) { const { address, signature, message, timestamp } = await req.json(); // 1. Check timestamp (5 min window) if (Date.now() - timestamp > 5 * 60 * 1000) { return Response.json({ error: "Expired" }, { status: 400 }); } // 2. Verify signature const isValid = nacl.sign.detached.verify( new TextEncoder().encode(message), bs58.decode(signature), bs58.decode(address) ); if (!isValid) { return Response.json({ error: "Invalid signature" }, { status: 401 }); } // 3. Check token balance using Helius DAS (API key server-side) try { const dasRes = await fetch(`https://mainnet.helius-rpc.com/?api-key=${HELIUS_API_KEY}`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ jsonrpc: "2.0", id: "1", method: "searchAssets", params: { ownerAddress: address, tokenType: "fungible", page: 1, limit: 1000, }, }), }); const dasData = await dasRes.json(); const items = dasData.result?.items || []; const tokenAsset = items.find((item: any) => item.id === TOKEN_MINT); const balance = tokenAsset?.token_info?.balance || 0; const decimals = ...[truncated 2159 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Add an endpoint that issues a cryptographically random, short-lived nonce. 2. Store the nonce server-side with its intended wallet, creation time, purpose, and unused state. 3. Construct a canonical sign-in message containing the application domain, URI, wallet address, chain, nonce, issued-at time, expiration time, and intended action. 4. Reconstruct the canonical message on the server rather than trusting a client-supplied message. 5. Reject timestamps that are either too old or too far in the future. 6. Atomically consume each nonce after successful verification. 7. Use short-lived access tokens and rotate signing secrets appropriately. 8. Re-verify current token ownership for sensitive actions. 9. Apply request rate limiting and structured validation to malformed addresses and signatures. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
references/frontend-security.md:27
Finding
Authenticated Helius Proxy Forwards Arbitrary Client Requests<![CDATA[ ## Vulnerability Details **File Location**: `references/frontend-security.md:27-108` **Additional Location**: `references/frontend-security.md:135-202` **Vulnerability Type**: Unrestricted authenticated API proxy **Risk Level**: High ### Vulnerable Code ```ts const HELIUS_API_KEY = process.env.HELIUS_API_KEY!; const HELIUS_BASE_URL = 'https://mainnet.helius-rpc.com'; const rateLimit = new Map<string, { count: number; resetAt: number }>(); const RATE_LIMIT_WINDOW = 60_000; const RATE_LIMIT_MAX = 60; function checkRateLimit(ip: string): boolean { const now = Date.now(); const entry = rateLimit.get(ip); if (!entry || now > entry.resetAt) { rateLimit.set(ip, { count: 1, resetAt: now + RATE_LIMIT_WINDOW }); return true; } if (entry.count >= RATE_LIMIT_MAX) return false; entry.count++; return true; } export async function POST( request: NextRequest, { params }: { params: Promise<{ path: string[] }> } ) { const ip = request.headers.get('x-forwarded-for') ?? 'unknown'; if (!checkRateLimit(ip)) { return NextResponse.json({ error: 'Rate limit exceeded' }, { status: 429 }); } const { path } = await params; const subpath = path.join('/'); const body = await request.json(); let url: string; if (subpath.startsWith('v0/') || subpath.startsWith('v1/')) { url = `https://api.helius.xyz/${subpath}?api-key=${HELIUS_API_KEY}`; } else { url = `${HELIUS_BASE_URL}/?api-key=${HELIUS_API_KEY}`; } const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body), }); const data = await response.json(); return NextResponse.json(data); } export async function GET( request: NextRequest, { params }: { params: Promise<{ path: string[] }> } ) { const ip = request.headers.get('x-forwarded-for') ?? 'unknown'; if (!checkRateLimit(ip)) { return NextResponse.json({ error: 'Rate limit exceeded' }, { status: 429 }); } const ...[truncated 2255 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Require application authentication and authorization before forwarding requests. 2. Replace catch-all forwarding with explicit endpoint and RPC-method allowlists. 3. Validate each request against a strict schema, including parameter ranges and maximum page sizes. 4. Enforce body-size, batch-size, and response-size limits. 5. Apply per-user, per-IP, per-method, and global quotas using shared durable storage. 6. Obtain client IP information only from a trusted platform API or a proxy header that the edge layer reliably overwrites. 7. Apply stricter limits to high-credit Wallet API, DAS, and historical-data calls. 8. Restrict CORS to approved application origins; do not use `Access-Control-Allow-Origin: *` for a billable authenticated proxy. 9. Add request logging, cost monitoring, abuse alerts, and a circuit breaker. 10. Return controlled error responses instead of blindly forwarding upstream content. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
references/frontend-security.md:252
Finding
Unauthenticated SSE Requests Create Unbounded Authenticated WebSocket Connections<![CDATA[ ## Vulnerability Details **File Location**: `references/frontend-security.md:252-310` **Vulnerability Type**: WebSocket connection amplification and resource exhaustion **Risk Level**: High ### Vulnerable Code ```ts // Server: connect to Helius WS, relay via SSE // app/api/stream/route.ts (Next.js App Router) import { NextRequest } from 'next/server'; import WebSocket from 'ws'; export async function GET(request: NextRequest) { const encoder = new TextEncoder(); const stream = new ReadableStream({ start(controller) { const ws = new WebSocket(`wss://mainnet.helius-rpc.com/?api-key=${process.env.HELIUS_API_KEY}`); ws.on('open', () => { ws.send(JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'accountSubscribe', params: [ request.nextUrl.searchParams.get('address'), { encoding: 'jsonParsed', commitment: 'confirmed' }, ], })); // Keep alive const pingInterval = setInterval(() => { if (ws.readyState === 1) ws.ping(); }, 30_000); ws.on('close', () => clearInterval(pingInterval)); }); ws.on('message', (data: Buffer) => { const msg = JSON.parse(data.toString()); if (msg.method) { controller.enqueue(encoder.encode(`data: ${JSON.stringify(msg.params)}\n\n`)); } }); request.signal.addEventListener('abort', () => { ws.close(); controller.close(); }); }, }); return new Response(stream, { headers: { 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', Connection: 'keep-alive', }, }); } ``` ### Technical Analysis Every incoming HTTP request creates a new outbound WebSocket authenticated with the server's Helius API key. The endpoint has no authentication, authorization, per-user connection quota, global connection quota, request rate limit, idle timeout, or maximum connection life ...[truncated 1272 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Authenticate and authorize every SSE client. 2. Validate the address as a canonical Solana public key before opening an upstream subscription. 3. Enforce per-user, per-IP, and global concurrent-connection limits. 4. Apply connection-attempt rate limits using shared durable storage. 5. Set idle timeouts and an absolute maximum connection lifetime. 6. Multiplex multiple client subscriptions over a bounded pool of upstream Helius WebSockets. 7. Deduplicate subscriptions to the same address and fan out events to authorized clients. 8. Handle upstream errors and abnormal closures with bounded backoff. 9. Monitor active connections, rejected attempts, memory, and provider quota utilization. 10. Reject requests before creating a `ReadableStream` or upstream socket when capacity is unavailable. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (52)

Credential Access

High
Category
Privilege Escalation
Content
### Next.js

```bash
# .env.local (gitignored, dev only)
HELIUS_API_KEY=your-api-key-here

# NEVER use NEXT_PUBLIC_ prefix for API keys!
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
### Next.js

```bash
# .env.local (gitignored, dev only)
HELIUS_API_KEY=your-api-key-here

# NEVER use NEXT_PUBLIC_ prefix for API keys!
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Rp1

Medium
Category
MCP Rug Pull
Confidence
90% confidence
Finding
The skill instructs users to install an MCP server via `npx helius-mcp@latest`, which is effectively an unpinned dependency and allows future upstream changes to alter what gets executed. If the package is compromised or a breaking/malicious release is published, users may install and run unexpected code in a trusted workflow.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
- For embedded wallets (`"google"`, `"apple"` providers): `signTransaction` is NOT supported — use `signAndSendTransaction` instead (submits through Phantom's infrastructure)
- Build transactions with `@solana/kit`: `pipe(createTransactionMessage(...), ...)` → `compileTransaction()` — both `signTransaction` and `signAndSendTransaction` accept the compiled output
- ALWAYS handle user rejection gracefully — this is not an error to retry
- NEVER auto-approve transactions — each must be explicitly approved by the user

### Frontend Security
- **NEVER expose Helius API keys in client-side code** — no `NEXT_PUBLIC_HELIUS_API_KEY`, no API key in browser `fetch()` URLs, no API key in WebSocket URLs visible in network tab
Confidence
85% confidence
Finding
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.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The instructions require the agent to 'ALWAYS use Orb' and 'never' use any other explorer, which imposes a specific service choice on users without opt-in or documented necessity. This is a natural-language policy concern because it forces a particular external destination rather than offering user choice or context-specific flexibility.

Rp1

Medium
Category
MCP Rug Pull
Confidence
90% confidence
Finding
This second reference repeats the same unpinned MCP installation pattern, again exposing users to supply-chain risk from whatever version is current at execution time. Repetition in resource sections increases the chance that users copy the insecure command directly.

Skill Enumeration

Medium
Category
Agent Snooping
Content
SKILL_NAME="helius-phantom"
SKILL_DIR="$(cd "$(dirname "$0")" && pwd)"

# Default: install to personal skills
TARGET_BASE="$HOME/.claude/skills"
MODE="personal"
Confidence
85% confidence
Finding
Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Rp1

Medium
Category
MCP Rug Pull
Confidence
96% confidence
Finding
The installer instructs users to add an MCP server using `npx helius-mcp@latest`, which pulls and executes the latest published package at runtime rather than a pinned, reviewed version. This creates a supply-chain risk: a compromised publisher account or malicious upstream update could cause users to execute attacker-controlled code when following the installation instructions.

Rp1

Medium
Category
MCP Rug Pull
Confidence
83% confidence
Finding
The documentation recommends running `npx -y create-solana-dapp@latest`, which fetches and executes the latest package version at install time without pinning. This creates a supply-chain risk: if the upstream package is compromised or a breaking/malicious release is published, users following the docs could execute unreviewed code on their machines.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
const isConnected = sdk.solana.isConnected();
```

## Auto-Confirm (Injected Provider Only)

```ts
import { NetworkId } from "@phantom/browser-sdk";
Confidence
85% confidence
Finding
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.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The auto-confirm section explains how to enable automatic confirmation of transactions but does not warn that this reduces an important user-consent safeguard. In a wallet/transaction-signing context, readers may enable it broadly without understanding that malicious or unintended transactions could be approved with less scrutiny.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
import { NetworkId } from "@phantom/browser-sdk";

// Enable for specific chains
await sdk.enableAutoConfirm({
  chains: [NetworkId.SOLANA_MAINNET]
});
Confidence
85% confidence
Finding
The example shows enabling auto-confirm for a chain, which can allow transactions to proceed with reduced per-transaction user verification. In a frontend Solana wallet integration context, this increases the chance that compromised UI logic, malicious dependencies, or unintended transaction generation could lead to silent approvals.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
});

// Enable for all supported chains
await sdk.enableAutoConfirm();

// Disable
await sdk.disableAutoConfirm();
Confidence
90% confidence
Finding
The example `await sdk.enableAutoConfirm();` enables auto-confirm for all supported chains, which materially broadens the attack surface. If adopted as written, a compromised dApp session or buggy application logic could cause cross-chain transactions to be approved without normal user review.

External Transmission

Medium
Category
Data Exfiltration
Content
let url: string;
  if (subpath.startsWith('v0/') || subpath.startsWith('v1/')) {
    // Enhanced Transactions or Wallet API
    url = `https://api.helius.xyz/${subpath}?api-key=${HELIUS_API_KEY}`;
  } else {
    // RPC / DAS / Priority Fee
    url = `${HELIUS_BASE_URL}/?api-key=${HELIUS_API_KEY}`;
Confidence
50% 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
let url: string;
  if (subpath.startsWith('v0/') || subpath.startsWith('v1/')) {
    // Enhanced Transactions or Wallet API
    url = `https://api.helius.xyz/${subpath}?api-key=${HELIUS_API_KEY}`;
  } else {
    // RPC / DAS / Priority Fee
    url = `${HELIUS_BASE_URL}/?api-key=${HELIUS_API_KEY}`;
Confidence
50% 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
const searchParams = request.nextUrl.searchParams.toString();
  const qs = searchParams ? `&${searchParams}` : '';

  const url = `https://api.helius.xyz/${subpath}?api-key=${HELIUS_API_KEY}${qs}`;

  const response = await fetch(url);
  const data = await response.json();
Confidence
79% confidence
Finding
The GET proxy forwards arbitrary client-supplied query parameters directly to the upstream Helius API alongside the server-held API key. In this form, the backend can become an unvalidated open proxy for authenticated upstream requests, allowing abuse of your Helius credits, access to unintended API operations, or bypass of intended client restrictions.

External Transmission

Medium
Category
Data Exfiltration
Content
app.all('/api/helius/v0/*', async (req, res) => {
  const subpath = req.path.replace('/api/helius/', '');
  const url = `https://api.helius.xyz/${subpath}?api-key=${HELIUS_API_KEY}`;

  const response = await fetch(url, {
    method: req.method,
Confidence
81% confidence
Finding
This Express example proxies any request matching /api/helius/v0/* to Helius using the server API key, with the subpath derived from the request path and little visible validation. That creates a generic authenticated relay that attackers can abuse to consume paid API capacity or invoke upstream endpoints your application did not intend to expose.

External Transmission

Medium
Category
Data Exfiltration
Content
let targetUrl: string;

    if (subpath.startsWith('v0/') || subpath.startsWith('v1/')) {
      targetUrl = `https://api.helius.xyz/${subpath}?api-key=${env.HELIUS_API_KEY}`;
    } else {
      targetUrl = `https://mainnet.helius-rpc.com/?api-key=${env.HELIUS_API_KEY}`;
    }
Confidence
90% confidence
Finding
The Cloudflare Worker returns `Access-Control-Allow-Origin: *` while forwarding authenticated requests with the server-held Helius API key. This effectively exposes your backend proxy to any website on the internet, enabling cross-origin abuse from arbitrary browsers to spend your credits and potentially access backend-exposed upstream capabilities.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The onboarding flow documents `agenticSignup`, `upgradePlan`, and renewal/payment behavior that can spend SOL and USDC, but it does not clearly foreground that these actions initiate real fund transfers and subscription charges. In an agent-oriented context, this is especially risky because users may treat setup steps as informational and not realize a tool invocation can immediately execute a payment.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The document states that API keys, JWTs, and the signup keypair are persisted to shared/local config, but it does not prominently warn users about the sensitivity of those credentials or the local compromise implications. On a shared machine, developer workstation, or CI-like environment, this can lead to unauthorized account access, billing abuse, or wallet misuse if filesystem permissions and secret handling are weak.

Rp1

Medium
Category
MCP Rug Pull
Confidence
87% confidence
Finding
The installation command uses `npx helius-mcp@latest`, which pulls a mutable package version at execution time. In a security-sensitive workflow involving API keys, JWTs, and payment-capable tooling, this increases supply-chain risk because a compromised or newly introduced package version could be executed without review or reproducibility guarantees.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The guidance strongly recommends routing signed transactions through third-party Helius/Jito infrastructure and mandates `skipPreflight: true`, but it does not prominently warn users about the trust, privacy, and failure-mode implications. In a frontend wallet/transaction skill, omitting that warning is dangerous because developers may unknowingly ship flows where users sign transactions that are externally relayed without local safety checks, increasing the chance of failed, opaque, or privacy-sensitive submissions.

Behavior Manipulation

Medium
Category
Prompt Injection
Content
## MCP Tools

All Wallet API endpoints have direct MCP tools. ALWAYS use these instead of generating raw API calls:

| MCP Tool | Endpoint | What It Does |
|---|---|---|
Confidence
70% confidence
Finding
Subtle instructions detected that may alter agent decision-making or introduce hidden biases.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The guidance explicitly promotes wallet attribution, funding-source tracing, and compliance/sybil analysis without any caution about privacy sensitivity, false positives, or appropriate authorization. In a frontend integration skill, this can normalize surveillance-style use and encourage downstream apps or agents to perform invasive profiling of users and wallets without guardrails.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The sybil detection section tells users to group wallets by shared funder and treat clusters as suspicious, but offers no warning that shared funders can have benign explanations such as exchange withdrawals, custodial flows, or funding hubs. This can lead to overbroad suspicion, mislabeling, and automated harmful decisions against legitimate users.

Static analysis

Detected: suspicious.exposed_secret_literal

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
references/helius-onboarding.md:95