Back to skill

Security audit

Nexwave Gateway

Security checks for vulnerabilities and agentic risk

Overview

This testnet USDC skill is coherent, but needs Review because a balance check can create Circle wallets and the setup/runtime gives unpinned code access to powerful Circle credentials.

Review before installing. Use only a limited testnet Circle account, keep Circle API and entity secrets out of shared terminals/logs, pin dependencies or add a reviewed lockfile before running setup, and expect check-balance.js to be capable of creating missing Circle wallets. Run deposit.js and transfer.js only when you intend to approve, deposit, sign, and mint the hardcoded testnet USDC amounts.

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

T08 · Insecure Dependencies

Warning
Location
setup.sh:20
Finding
Unpinned Third-Party Dependencies Create a Supply-Chain Risk## Vulnerability Details **File Location**: `setup.sh`, lines 20-22 **Vulnerability Type**: Unpinned dependency installation **Risk Level**: Medium ### Vulnerable Code ```bash # Install dependencies echo "📦 Installing dependencies..." npm install viem dotenv @circle-fin/developer-controlled-wallets ``` ### Technical Analysis The setup script installs three packages without exact versions. The project also contains no reviewed lockfile or integrity constraints. Consequently, each installation may resolve different package and transitive-dependency versions. This is particularly sensitive because the installed Circle SDK subsequently receives `CIRCLE_API_KEY` and `CIRCLE_ENTITY_SECRET`, while the installed packages execute in a process capable of initiating wallet operations. A compromised package release, compromised transitive dependency, or malicious lifecycle script could execute with the user's local permissions and access secrets available to the setup or runtime process. This finding does not establish that the named packages are malicious. It identifies the absence of reproducible, integrity-controlled dependency resolution. ### Attack Path 1. An attacker compromises a listed package, one of its transitive dependencies, or the associated package publication account. 2. The attacker publishes a malicious version that satisfies the unconstrained installation request. 3. A user follows the documented instructions and runs `bash setup.sh`. 4. `npm install` resolves and installs the attacker-controlled release. 5. Malicious code executes through an installation lifecycle hook or when the dependency is imported. 6. The code may read Circle credentials from the environment or `.env` file, alter wallet API requests, or substitute transaction parameters. 7. The attacker may then use exposed credentials or manipulated wallet operations within the authority granted to the Circle developer-controlled wallet configurat ...[truncated 704 chars]
Remediation
## Remediation Suggestions 1. Pin every direct dependency to an exact reviewed version rather than using unconstrained package names. 2. Generate and commit a lockfile after reviewing the resolved dependency graph. 3. Replace `npm install` in automated setup with `npm ci` so installation fails if the lockfile and manifest differ. 4. Use package-manager integrity verification and retain the lockfile's integrity hashes. 5. Disable dependency lifecycle scripts where compatible, for example with `npm ci --ignore-scripts`, and explicitly run only required, reviewed build steps. 6. Audit direct and transitive dependencies using vulnerability and provenance tooling. 7. Run setup under a minimally privileged account without wallet credentials in the environment. 8. Make Circle credentials available only to the specific runtime command that requires them. 9. Apply Circle-side least-privilege policies, transaction limits, and monitoring to reduce the impact of a dependency compromise.

T09 · Insecure Skill Coding Practices

Note
Location
circle-wallet-client.js:42
Finding
Read-Only Balance Command Silently Creates Wallets## Vulnerability Details **File Location**: `circle-wallet-client.js`, lines 42-88; triggered by `setup-gateway.js`, lines 81-82, and `check-balance.js`, line 1 **Vulnerability Type**: Unexpected privileged side effect and failure to separate discovery from provisioning **Risk Level**: Low ### Vulnerable Code ```js async init() { console.log("🔐 Initializing Circle Programmable Wallets..."); // List existing wallets in the set const response = await this.client.listWallets({ walletSetId: this.walletSetId, }); const existingWallets = response.data?.wallets || []; // Map existing wallets by blockchain for (const w of existingWallets) { for (const [chainName, blockchain] of Object.entries(BLOCKCHAIN_MAP)) { if (w.blockchain === blockchain && w.state === "LIVE") { this.wallets[chainName] = { walletId: w.id, address: w.address, blockchain, }; } } } // Create wallets for any missing chains const missingChains = Object.entries(BLOCKCHAIN_MAP).filter( ([name]) => !this.wallets[name] ); if (missingChains.length > 0) { console.log( ` Creating wallets for: ${missingChains.map(([, b]) => b).join(", ")}` ); const createResponse = await this.client.createWallets({ blockchains: missingChains.map(([, blockchain]) => blockchain), count: 1, walletSetId: this.walletSetId, }); const created = createResponse.data?.wallets || []; for (const w of created) { for (const [chainName, blockchain] of missingChains) { if (w.blockchain === blockchain) { this.wallets[chainName] = { walletId: w.id, address: w.address, blockchain, }; } } } } } ``` The initialization is executed automatically at module import: ```js // Initialize Circle Programmab ...[truncated 2833 chars]
Remediation
## Remediation Suggestions 1. Split initialization into separate methods such as `discoverWallets()` and `provisionMissingWallets()`. 2. Ensure `check-balance.js` calls only read-only wallet discovery and balance APIs. 3. Move wallet creation into a dedicated setup or provisioning command. 4. Display the exact chains and wallet set that will be modified, then require explicit confirmation before creation. 5. Add a non-interactive opt-in flag, such as `--create-missing-wallets`, for controlled automation. 6. Remove top-level privileged side effects from `setup-gateway.js`; expose an explicit initialization function instead. 7. Fail safely with a clear message when a required wallet is absent rather than silently creating one. 8. Use separate credentials or Circle-side roles for read-only inspection and wallet administration where supported. 9. Add tests asserting that balance-check execution never invokes `createWallets` or any transaction API.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • 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
Findings (10)

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding
The skill makes strong security claims such as 'no raw private keys' and use of Circle Programmable Wallets, but the provided skill file does not substantiate those guarantees and references external scripts not included here. In a financial skill that handles cross-chain USDC flows and depends on secrets, this mismatch can mislead users and agents into trusting unsafe implementations, potentially resulting in insecure key handling, unauthorized signing flows, or loss of funds.

Credential Access

High
Category
Privilege Escalation
Content
cp "$SKILL_DIR/$f" ./ 2>/dev/null || true
done

# Create .env template (if not already configured)
if [ ! -f .env ]; then
  echo "🔧 Creating .env template..."
  cat > .env << 'EOF'
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
cp "$SKILL_DIR/$f" ./ 2>/dev/null || true
done

# Create .env template (if not already configured)
if [ ! -f .env ]; then
  echo "🔧 Creating .env template..."
  cat > .env << 'EOF'
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
cp "$SKILL_DIR/$f" ./ 2>/dev/null || true
done

# Create .env template (if not already configured)
if [ ! -f .env ]; then
  echo "🔧 Creating .env template..."
  cat > .env << 'EOF'
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
cp "$SKILL_DIR/$f" ./ 2>/dev/null || true
done

# Create .env template (if not already configured)
if [ ! -f .env ]; then
  echo "🔧 Creating .env template..."
  cat > .env << 'EOF'
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
cp "$SKILL_DIR/$f" ./ 2>/dev/null || true
done

# Create .env template (if not already configured)
if [ ! -f .env ]; then
  echo "🔧 Creating .env template..."
  cat > .env << 'EOF'
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
cp "$SKILL_DIR/$f" ./ 2>/dev/null || true
done

# Create .env template (if not already configured)
if [ ! -f .env ]; then
  echo "🔧 Creating .env template..."
  cat > .env << 'EOF'
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The README instructs users to export long-lived Circle credentials and then run scripts that can query balances, deposit USDC, and transfer funds, but it does not warn that these secrets grant wallet/API authority or that the commands may move real assets. In an agent-skill context, this is more dangerous because operators may install and run setup steps with limited review, causing accidental secret exposure, misuse in shell history/logs, or unintended fund movements.

Lp3

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding
The skill requires environment secrets and instructs users to run networked scripts, but it does not declare an explicit tool scope such as permissions or allowed-tools. In an agent ecosystem, this creates an authorization blind spot: the runtime or reviewer cannot easily constrain or audit access to env and network capabilities before execution, increasing the chance of unintended secret exposure or outbound requests.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
This method directly submits on-chain contract execution transactions through Circle's wallet API with no built-in authorization, policy checks, transaction allowlisting, or user confirmation step in this file. In an agent skill context, that means any upstream prompt injection, tool misuse, or logic bug could cause real fund-moving approvals, deposits, or mints to be executed automatically, which is especially dangerous for ERC-20 approve flows and cross-chain gateway operations.

Static analysis

No suspicious patterns detected.