T08 · Insecure Dependencies
- Location
references/helius-onboarding.md:188- Finding
Mutable MCP Dependency Is Downloaded and Executed Without Version Pinning
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
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.
references/helius-onboarding.md:188Mutable MCP Dependency Is Downloaded and Executed Without Version Pinning
references/payments.md:289Payment Confirmation Accepts an Unrelated Successful Transaction
references/token-gating.md:87Client-Controlled Future Timestamp Enables Indefinite Authentication Replay
references/frontend-security.md:27Authenticated Helius Proxy Forwards Arbitrary Client Requests
references/frontend-security.md:252Unauthenticated SSE Requests Create Unbounded Authenticated WebSocket Connections
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
# .env.local (gitignored, dev only)
HELIUS_API_KEY=your-api-key-here
# NEVER use NEXT_PUBLIC_ prefix for API keys!
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
# .env.local (gitignored, dev only)
HELIUS_API_KEY=your-api-key-here
# NEVER use NEXT_PUBLIC_ prefix for API keys!
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.
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.
- 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
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.
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 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.
SKILL_NAME="helius-phantom"
SKILL_DIR="$(cd "$(dirname "$0")" && pwd)"
# Default: install to personal skills
TARGET_BASE="$HOME/.claude/skills"
MODE="personal"
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.
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.
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.
const isConnected = sdk.solana.isConnected();
## Auto-Confirm (Injected Provider Only)
```ts
import { NetworkId } from "@phantom/browser-sdk";
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.
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.
import { NetworkId } from "@phantom/browser-sdk";
// Enable for specific chains
await sdk.enableAutoConfirm({
chains: [NetworkId.SOLANA_MAINNET]
});
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.
});
// Enable for all supported chains
await sdk.enableAutoConfirm();
// Disable
await sdk.disableAutoConfirm();
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
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}`;
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
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}`;
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.
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();
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.
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,
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.
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}`;
}
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.
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.
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.
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.
Subtle instructions detected that may alter agent decision-making or introduce hidden biases.
## 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 |
|---|---|---|
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.
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.