Back to skill

Security audit

Tator Trader - AI Trading

Security checks for vulnerabilities and agentic risk

Overview

This is a disclosed crypto trading skill, but one wallet example can broadcast remote-built transactions without enforcing verification first.

Review this skill carefully before installing. Use only a dedicated low-balance wallet, never paste seed phrases or private keys, and do not use the AgentWallet broadcast sample as-is. Require explicit user approval, decode and simulate transactions, verify chainId/to/value/calldata, and enforce spending limits before any signing or broadcast.

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
SKILL.md:189
Finding

Unverified Remote Transactions Are Forwarded for Signing and Broadcast

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 189–207
Vulnerability Type: Missing transaction validation before privileged wallet operation
Risk Level: High

Vulnerable Code

javascript
if (result.type === 'transaction') {
  for (const tx of result.transactions) {
    // VERIFY before signing — check to, value, chainId, description
    const broadcast = await fetch(
      'https://frames.ag/api/wallets/{username}/actions/send-transaction',
      {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${process.env.AGENTWALLET_API_TOKEN}`,
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          chainId: tx.chainId, to: tx.to, data: tx.data, value: tx.value
        })
      }
    );
    console.log(`TX sent: ${(await broadcast.json()).hash}`);
  }
}

Technical Analysis

The example forwards every transaction returned by the remote Tator API directly to AgentWallet's privileged send-transaction endpoint. Although a comment instructs the caller to verify the transaction, no executable validation is performed.

The implementation does not enforce:

  • The expected chain ID from the original user request.
  • An allowlist of authorized destination contracts or recipient addresses.
  • A maximum native-token value.
  • Decoded calldata and permitted function selectors.
  • Approval spender and allowance restrictions.
  • Consistency between the transaction and the user's original amount, token, recipient, and operation.
  • Transaction simulation or explicit user confirmation.

The AgentWallet API token grants access to a wallet operation capable of signing and broadcasting transactions. Consequently, values controlled by the remote response cross a trust boundary and reach a financially privileged operation without effective validation. The documentation elsewhere recommends verification, but those textual ...[truncated 1831 chars]

Remediation
View remediation

Remediation Suggestions

Replace the verification comment with mandatory, fail-closed validation before invoking the wallet API:

  1. Bind every response to the original request, including the expected chain, operation, token, recipient, and maximum amount.
  2. Reject missing, malformed, unexpected, or additional transactions.
  3. Maintain chain-specific allowlists of verified router, bridge, and protocol contracts.
  4. Decode calldata rather than trusting the response's human-readable description.
  5. Allow only function selectors required for the requested operation.
  6. For approvals, decode both spender and amount. Reject unknown spenders and unlimited approvals; approve only the exact required amount where possible.
  7. Enforce strict native-value and token-amount limits derived from explicit user authorization.
  8. Simulate each transaction and evaluate asset changes before signing.
  9. Require explicit human confirmation for transfers, approvals, leveraged positions, and transactions above a conservative threshold.
  10. Use a dedicated wallet with minimal funds and narrowly scoped wallet-provider policies.
  11. Stop the entire sequence on any validation, simulation, signing, or confirmation failure.
  12. Record the normalized user request, decoded transaction, validation result, and transaction hash in an audit log without recording bearer tokens.

A hardened flow should resemble:

javascript
for (const tx of result.transactions) {
  const verification = await verifyTransaction({
    tx,
    expectedChainId,
    originalRequest,
    allowedContracts,
    maximumValue
  });

  if (!verification.safe) {
    throw new Error(
      `Transaction rejected: ${verification.warnings.join('; ')}`
    );
  }

  const simulation = await simulateTransaction(tx);
  if (!simulation.success || simulation.hasUnexpectedAssetChanges) {
    throw new Error('Transaction simulation failed safety checks');
  }

  await req
...[truncated 91 chars]
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (7)

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · SKILL.md (reported line 150)May include surrounding context.

Pattern A: Sponge Wallet (Recommended — No Raw Keys)

bash
curl -sS -X POST "https://api.wallet.paysponge.com/api/x402/fetch" \
  -H "Authorization: Bearer $SPONGE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · SKILL.md (reported line 150)May include surrounding context.

Pattern A: Sponge Wallet (Recommended — No Raw Keys)

bash
curl -sS -X POST "https://api.wallet.paysponge.com/api/x402/fetch" \
  -H "Authorization: Bearer $SPONGE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · SKILL.md (reported line 170)May include surrounding context.

Pattern B: AgentWallet (No Raw Keys)

javascript
const response = await fetch('https://frames.ag/api/wallets/{username}/actions/x402/fetch', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${process.env.AGENTWALLET_API_TOKEN}`,

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · SKILL.md (reported line 192)May include surrounding context.

md
if (result.type === 'transaction') {
  for (const tx of result.transactions) {
    // VERIFY before signing — check to, value, chainId, description
    const broadcast = await fetch(
      'https://frames.ag/api/wallets/{username}/actions/send-transaction',
      {
        method: 'POST',

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

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.

Content

Scanner excerpt · SKILL.md (reported line 251)May include surrounding context.

Tator NEVER receives your private key. Tator CANNOT execute without your signature. The worst Tator can do is return a bad transaction. The worst YOU can do is sign it without checking.

text

## Payment Networks (14)

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · references/REFERENCE.md (reported line 194)May include surrounding context.

md
token: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'
});

const response = await fetch('https://x402.quickintel.io/v1/tator/prompt', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

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.

Content

Scanner excerpt · references/REFERENCE.md (reported line 277)May include surrounding context.

}

text

> **For automated agents:** Never enable fully automatic signing without verification checks. Human-in-the-loop for high-value transactions is strongly recommended.

## Complete Example: Scan Then Buy