Back to skill

Security audit

Kite Agent Smart Wallet V3

Security checks for vulnerabilities and agentic risk

Overview

This Telegram wallet skill matches its stated testnet wallet-control purpose, but it gives chat commands high-impact wallet authority without enough in-skill authorization, confirmation, or clear scoping.

Review carefully before installing. Use only a low-value testnet private key unless the command handler is changed to enforce authenticated owners, route user transfers through the intended smart wallet and its limits, require confirmations for transfers and permission changes, avoid wildcard session-key permissions, and hide operator wallet balances from ordinary users.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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 (3)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
kite-wallet.js:67
Finding

Unauthenticated Command Handler Allows Spending from the Shared Operator Wallet

Content
View full analysis
<数量>\n\n` + `例: /kite send 0xABC... 0.1`; } const toAddress = args[0]; const amount = args[1]; // Validate address if (!ethers.isAddress(toAddress)) { return '❌ 无效的地址格式'; } // Validate amount const amountWei = ethers.parseEther(amount); const balance = await provider.getBalance(wallet.address); if (amountWei > balance) { return `❌ 余额不足\n\n` + `当前余额: ${ethers.formatEther(balance)} KITE\n` + `尝试转账: ${amount} KITE`; } const tx = await wallet.sendTransaction({ to: toAddress, value: amountWei }); await tx.wait(); ``` ### Technical Analysis `init()` creates a single process-wide ethers signer from the configured private key. Every invocation of `handleKiteCommand()` subsequently uses that shared signer. The handler accepts a `userId`, but it does not authenticate that identity, compare it against an owner allowlist, check a role, or verify a user signature before executing `/kite send`. The `userId` is not used at all in the transfer branch. Address and balance validation only validate transaction parameters; they do not establish whether the caller is authorized to spend the funds. Consequently, any caller whose message is routed to this handler can cause the shared operator wallet to sign and broadcast a native-token transfer to an arbitrary valid address. Security would ...[truncated 1291 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
kite-wallet.js:145
Finding

Transfer Operation Bypasses the Advertised Smart-Wallet Spending Limit

Content
View full analysis
<数量>\n\n` + `例: /kite send 0xABC... 0.1`; } const toAddress = args[0]; const amount = args[1]; // Validate address if (!ethers.isAddress(toAddress)) { return '❌ 无效的地址格式'; } // Validate amount const amountWei = ethers.parseEther(amount); const balance = await provider.getBalance(wallet.address); if (amountWei > balance) { return `❌ 余额不足\n\n` + `当前余额: ${ethers.formatEther(balance)} KITE\n` + `尝试转账: ${amount} KITE`; } const tx = await wallet.sendTransaction({ to: toAddress, value: amountWei }); await tx.wait(); ``` A spending limit is configured on a different, user-specific smart wallet: ```js const tx = await factory.createWallet(agentAddr, ethers.parseEther('10')); await tx.wait(); ``` ```js if (action === 'set') { if (args.length < 2) { return '❌ 用法: /kite limit set <数量>'; } const newLimit = args[1]; const walletContractWrite = new ethers.Contract(walletAddr, WALLET_ABI, wallet); const tx = await walletContractWrite.updateSpendingLimit(ethers.parseEther(newLimit)); await tx.wait(); return `✅ *限额已更新!*\n\n新限额: *${newLimit} KITE*`; } ``` ### Technical Analysis Wallet creation and limit management operate on the user-specific smart-wallet contract returned by `getUserWallet(userId)`. In contrast, `/kite send` neither resolves the user’s smart wallet nor calls its `execute(bytes)` function. ...[truncated 1656 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
kite-wallet.js:204
Finding

Session Keys Are Granted Unrestricted Function Scope

Content
View full analysis
`. 3. The Skill submits the session-key registration with an unrestricted function scope. 4. The session key is compromised, malicious, or operated beyond its intended purpose. 5. The key invokes any smart-wallet function covered by the contract’s “allow all functions” interpretation. 6. Contract-side monetary or other restrictions may still apply, but function-level isolation is absent. ### Impact Assessment A session key receives more authority than is necessary for a narrowly defined task. If compromised, it may access every wallet operation that the deployed contract makes available to unrestricted session keys, rather than only ...[truncated 320 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (14)

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

Session keys are added with ['0x00000000'], which the code comments interpret as allowing all functions. That gives the grantee far broader authority than the command wording implies, so a compromised or malicious session key could invoke sensitive wallet functionality within the granted spending limit or broader contract semantics.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The session-key addition appears to authorize all functions while providing no clear disclosure to the user that full or near-full wallet capabilities are being delegated. This combination of overbroad permissioning and poor disclosure significantly raises the risk of unauthorized asset movement or wallet reconfiguration.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: ws==8.17.1 — 2 advisory(ies): CVE-2026-45736 (ws: Uninitialized memory disclosure); CVE-2026-48779 (ws: Memory exhaustion DoS from tiny fragments and data chunks)

High
Category
Supply Chain
Confidence
95% confidence
Finding

The lockfile pins the transitive dependency ws to version 8.17.1, which the provided analysis identifies as affected by memory disclosure and memory-exhaustion denial-of-service advisories. Because ethers depends on ws for WebSocket connectivity, any skill feature that opens WebSocket connections to untrusted or semi-trusted endpoints could expose the agent process to crashes, resource exhaustion, or unintended memory disclosure.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The README documents Telegram commands that can create wallets, send funds, and add spending sessions/limits, but it provides no warning that these operations can change wallet state or move real assets. In a wallet-control skill, missing safety guidance increases the risk of accidental fund transfers, unsafe user assumptions, and misuse through a chat interface where commands are easy to trigger.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill exposes commands for sending funds, adding session-key authorizations, and changing spending limits, but it does not clearly warn users that these actions directly modify on-chain assets and wallet permissions. In a Telegram-controlled wallet context, this omission increases the risk of accidental irreversible transactions or unintended delegation of authority, especially because users may treat chat commands as low-risk administrative actions.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

User-facing command responses throughout the handler are written in Chinese, including errors, help text, and success messages, with no opt-in or alternate locale support. This constitutes a language/locale policy concern because the skill imposes a specific language on all users without providing choice or justification.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The /kite balance command discloses the operator's main wallet balance to any user invoking the skill, even though the feature context suggests a user-specific wallet inquiry. This leaks sensitive operational financial information that can aid targeting, social engineering, and abuse decisions by attackers.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The send command immediately performs an on-chain transfer after parsing user input, with no secondary confirmation for an irreversible asset movement. In chat-driven interfaces, mis-typed addresses, prompt injection via relayed text, or accidental invocation can directly cause loss of funds.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

Adding a session key changes on-chain authorization state but the skill does not warn the user about the security implications before executing. Users may unknowingly delegate wallet control, and in a conversational context that can happen through misunderstanding or manipulated prompts.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

Removing a session key is a security-sensitive change to wallet access controls. The code performs the on-chain authorization update directly and only informs the user after completion, without any pre-action disclosure or confirmation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

Updating the spending limit changes wallet control policy on-chain without any warning or confirmation. An accidental or manipulated increase can weaken safeguards around future spending, while a drastic decrease can disrupt intended wallet operations.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The user-facing README content is presented in Chinese only, with no indication that other languages are supported or that the language choice is intentional and documented. This can violate language/locale policy when a skill imposes a specific language without user opt-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

SQP-3 applies to natural-language policy issues in all file types, including markdown. The file forces a specific language for all user-facing instructions and command explanations, with no opt-in, alternative language, or explanation that the skill is intended only for a Chinese-speaking or region-specific audience.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

The dependency uses a caret range (^6.16.0), which permits automatic installation of newer minor and patch releases. This weakens supply-chain reproducibility and can unexpectedly introduce vulnerable or malicious upstream code if the dependency or resolution path changes.

Content

Scanner excerpt · package.json (reported line 3)May include surrounding context.

json
{
  "dependencies": {
    "ethers": "^6.16.0"
  }
}

Static analysis

No suspicious patterns detected.