Back to skill

Security audit

Near Subaccount

Security checks for vulnerabilities and agentic risk

Overview

The skill does what it advertises, but it handles blockchain account and token operations with unsafe shell command construction and weak safeguards around destructive actions.

Review before installing. Use only in a test or low-value NEAR environment until the script replaces shell-string exec calls with argument-based process execution, validates all account IDs and amounts, and adds explicit confirmations or dry-run previews for delete and bulk distribute operations.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/subaccount.js:14
Finding
OS Command Injection Through Unvalidated NEAR CLI Arguments## Vulnerability Details **File Location**: `scripts/subaccount.js:14-17`, `scripts/subaccount.js:27-30`, `scripts/subaccount.js:43-46`, and `scripts/subaccount.js:68-69` **Vulnerability Type**: OS command injection through `child_process.exec` **Risk Level**: High ### Vulnerable Code ```js async function createSubaccount(subaccountName, masterAccount) { const subaccountId = `${subaccountName}.${masterAccount}`; const cmd = `near create-account ${subaccountId} --masterAccount ${masterAccount} --initialBalance 0.1 ${networkFlag}`; try { await execAsync(cmd); ``` ```js async function listSubaccounts(accountId) { const cmd = `near view ${accountId} list_subaccounts ${networkFlag}`; try { const { stdout } = await execAsync(cmd); ``` ```js async function deleteSubaccount(subaccountId, masterAccount) { const cmd = `near delete-account ${subaccountId} --beneficiaryId ${masterAccount} ${networkFlag}`; try { await execAsync(cmd); ``` ```js for (const subaccountId of subaccounts) { try { const cmd = `near send ${masterAccount} ${subaccountId} ${amount} ${networkFlag}`; await execAsync(cmd); ``` ### Technical Analysis The application builds shell command strings by directly interpolating values from command-line arguments, the `NEAR_ACCOUNT` environment variable, and an attacker-controllable JSON file. These strings are passed to the promisified form of `child_process.exec`. Unlike an API that executes a program with a separate argument array, `exec` sends the command string through a system shell. Consequently, shell metacharacters and constructs contained in values such as `subaccountName`, `masterAccount`, `accountId`, `subaccountId`, or `amount` are interpreted by the shell rather than treated solely as NEAR CLI arguments. The application does not validate these values against the NEAR account-ID syntax, constrain the amount to a positive decimal number, or ...[truncated 1837 chars]
Remediation
## Remediation Suggestions 1. Replace `child_process.exec` with `execFile` or `spawn`, passing every argument as a distinct array element and keeping shell execution disabled. ```js const { execFile } = require('child_process'); const { promisify } = require('util'); const execFileAsync = promisify(execFile); await execFileAsync('near', [ 'create-account', subaccountId, '--masterAccount', masterAccount, '--initialBalance', '0.1', '--networkId', 'testnet' ]); ``` 2. Apply the same argument-array approach to the `view`, `delete-account`, and `send` operations. Do not construct a command by concatenating or interpolating user-controlled strings. 3. Strictly validate every account identifier, including values from JSON and `NEAR_ACCOUNT`, against the exact NEAR account-ID rules. Reject whitespace, shell metacharacters, malformed labels, invalid lengths, and unexpected network suffixes. 4. Parse distribution amounts as numeric decimal values and enforce explicit minimum and maximum limits. Convert the validated value back to a canonical decimal string before passing it to the NEAR CLI. 5. Validate the entire distribution document before initiating any transfer. Reject unexpected properties, non-string entries, duplicate accounts, oversized arrays, and invalid destination accounts. 6. Do not treat shell escaping as the primary fix. Correct process invocation with `shell: false`, separate arguments, and strict domain validation provides stronger protection. 7. Add automated tests using inputs containing spaces, semicolons, quotes, command substitution, redirection operators, and newlines. The tests should verify that malicious input is rejected and never interpreted by a shell.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (7)

Missing User Warnings

High
Confidence
95% confidence
Finding
The delete command triggers `near delete-account` immediately after receiving CLI arguments, with no explicit confirmation prompt, dry-run mode, or additional safeguard for an irreversible blockchain operation. In this skill’s context, users are managing real accounts and funds, so a typo, automation mistake, or maliciously influenced input can permanently delete a subaccount and transfer remaining balance to the beneficiary.

Session Persistence

Medium
Category
Rogue Agent
Content
# NEAR Subaccount Manager Skill

Create and manage NEAR subaccounts from the command line.

## Installation
Confidence
60% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The README provides a destructive delete command for a NEAR subaccount without warning that deletion may be irreversible or may permanently affect account access, funds, and configuration. In a blockchain/account-management context, omission of safety guidance increases the chance of accidental destructive actions by users following copy-paste instructions.

Lp3

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill documents use of the NEAR_ACCOUNT environment variable but does not declare any tool scope, permissions, or allowed-tools metadata indicating access to environment data. This creates a trust and transparency gap: an agent may read sensitive environment configuration without explicit disclosure, making the skill more dangerous in automated environments where env access should be tightly declared.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The documented delete command performs a destructive account operation but provides no warning, confirmation prompt guidance, or recovery caveat. In an agent-driven or copy-paste workflow, this increases the chance of accidental deletion of blockchain accounts, where mistakes may be irreversible or operationally costly.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The bulk distribution feature describes sending NEAR to multiple accounts without warning that blockchain transfers are typically irreversible and may rapidly drain funds if the recipient list or amount is wrong. In an automation context, a malformed JSON file, wrong default account, or user misunderstanding could cause immediate financial loss at scale.

Missing User Warnings

Low
Confidence
77% confidence
Finding
The usage examples tell users to set `NEAR_ACCOUNT`, which establishes the account context for subsequent operations including creation, deletion, and distribution, but the documentation provides no caution about ensuring the correct active account or protecting associated wallet configuration. For a skill managing on-chain assets, missing context and safety warnings can lead to unintended actions on the wrong account.

Static analysis

No suspicious patterns detected.