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

Content
View full analysis

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
View 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'
]);
  1. 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.

  2. 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.

  3. 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.

  4. Validate the entire distribution document before initiating any transfer. Reject unexpected properties, non-string entries, duplicate accounts, oversized arrays, and invalid destination accounts.

  5. Do not treat shell escaping as the primary fix. Correct process invocation with shell: false, separate arguments, and strict domain validation provides stronger protection.

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

Content

No source excerpt is available for this finding.

Session Persistence

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

Content

Scanner excerpt · README.md (reported line 3)May include surrounding context.

md
# NEAR Subaccount Manager Skill

Create and manage NEAR subaccounts from the command line.

## Installation

Missing User Warnings

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

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

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.

Content

No source excerpt is available for this finding.

Missing User Warnings

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

Content

No source excerpt is available for this finding.

Missing User Warnings

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

Content

No source excerpt is available for this finding.

Missing User Warnings

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

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.