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

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
references/payments.md:289
Finding

Payment Confirmation Accepts an Unrelated Successful Transaction

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
references/token-gating.md:87
Finding

Client-Controlled Future Timestamp Enables Indefinite Authentication Replay

Content
View full analysis
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
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
references/frontend-security.md:27
Finding

Authenticated Helius Proxy Forwards Arbitrary Client Requests

Content
View full analysis
(); 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
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
references/frontend-security.md:252
Finding

Unauthenticated SSE Requests Create Unbounded Authenticated WebSocket Connections

Content
View full analysis
{ 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
View remediation
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
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · references/frontend-security.md (reported line 218)May include surrounding context.

Next.js

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

# NEVER use NEXT_PUBLIC_ prefix for API keys!

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · references/frontend-security.md (reported line 230)May include surrounding context.

Next.js

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

# NEVER use NEXT_PUBLIC_ prefix for API keys!

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.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
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.

Content

Scanner excerpt · SKILL.md (reported line 275)May include surrounding context.

md
- 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

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

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.

Content

No source excerpt is available for this finding.

Skill Enumeration

Medium
Category
Agent Snooping
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.

Content

Scanner excerpt · install.sh (reported line 7)May include surrounding context.

sh
SKILL_NAME="helius-phantom"
SKILL_DIR="$(cd "$(dirname "$0")" && pwd)"

# Default: install to personal skills
TARGET_BASE="$HOME/.claude/skills"
MODE="personal"

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.

Content

No source excerpt is available for this finding.

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.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
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.

Content

Scanner excerpt · references/browser-sdk.md (reported line 121)May include surrounding context.

const isConnected = sdk.solana.isConnected();

text

## Auto-Confirm (Injected Provider Only)

```ts
import { NetworkId } from "@phantom/browser-sdk";

Missing User Warnings

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
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.

Content

Scanner excerpt · references/browser-sdk.md (reported line 127)May include surrounding context.

md
import { NetworkId } from "@phantom/browser-sdk";

// Enable for specific chains
await sdk.enableAutoConfirm({
  chains: [NetworkId.SOLANA_MAINNET]
});

Autonomous Decision Making

Medium
Category
Excessive Agency
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.

Content

Scanner excerpt · references/browser-sdk.md (reported line 132)May include surrounding context.

md
});

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

// Disable
await sdk.disableAutoConfirm();

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · references/frontend-security.md (reported line 71)May include surrounding context.

md
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}`;

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · references/payments.md (reported line 296)May include surrounding context.

md
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}`;

External Transmission

Medium
Category
Data Exfiltration
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.

Content

Scanner excerpt · references/frontend-security.md (reported line 101)May include surrounding context.

md
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();

External Transmission

Medium
Category
Data Exfiltration
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.

Content

Scanner excerpt · references/frontend-security.md (reported line 161)May include surrounding context.

md
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,

External Transmission

Medium
Category
Data Exfiltration
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.

Content

Scanner excerpt · references/frontend-security.md (reported line 188)May include surrounding context.

md
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}`;
    }

Missing User Warnings

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Behavior Manipulation

Medium
Category
Prompt Injection
Confidence
70% confidence
Finding

Subtle instructions detected that may alter agent decision-making or introduce hidden biases.

Content

Scanner excerpt · references/helius-wallet-api.md (reported line 17)May include surrounding context.

md
## 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 |
|---|---|---|

Missing User Warnings

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.