Back to skill

Security audit

Mamo

Security checks for vulnerabilities and agentic risk

Overview

This is a DeFi wallet CLI for real Base mainnet funds, but it trusts local strategy addresses in a way that could route token approvals and deposits to an unsafe contract if the local config is changed.

Review carefully before installing or using with real funds. Use only a dedicated low-balance hot wallet, avoid storing the private key in committed or shared files, prefer dry-run first, and do not run deposits unless you trust and can protect ~/.config/mamo/strategies.json. The publisher should fix strategy validation so local entries are only hints and every asset-moving operation verifies registry membership, ownership, and trusted provenance on-chain.

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
src/utils/storage.ts:147
Finding

Unverified Local Strategy Address Can Redirect Token Approvals and Deposits

Content
View full analysis

Vulnerability Details

File Location:

  • src/utils/storage.ts:68-74, 147-149
  • src/clients/blockchain.ts:151-155, 166-188
  • src/commands/deposit.ts:94-101, 249-265, 284-293

Vulnerability Type: Improper validation of a security-sensitive contract address loaded from local storage
Risk Level: High

Vulnerable Code

The strategy configuration file is written without explicit restrictive permissions:

ts
export function saveLocalStrategies(data: LocalStrategiesData): void {
  writeFileSync(getStrategiesPath(), JSON.stringify(data, null, 2));
}

Strategy addresses are then read directly from the local JSON data:

ts
export function getLocalStrategyAddresses(walletAddress: Address): Address[] {
  const strategies = getLocalStrategiesForWallet(walletAddress);
  return Object.values(strategies).map((entry) => entry.address);
}

Locally supplied addresses are merged into the set of candidate strategies without calling the available registry validation function:

ts
// 2. Merge local strategies
const localAddresses = getLocalStrategyAddresses(walletAddress);
for (const addr of localAddresses) {
  if (!results.some((a) => a.toLowerCase() === addr.toLowerCase())) {
    results.push(addr);
  }
}

return results;

Candidate contracts are accepted solely because their token() method returns the requested token address:

ts
export async function findStrategyForToken(
  publicClient: PublicClient<Transport, Chain>,
  walletAddress: Address,
  tokenAddress: Address | null
): Promise<Address | null> {
  if (!tokenAddress) return null;

  const strategies = await getAllStrategies(publicClient, walletAddress);

  for (const addr of strategies) {
    try {
      const stratToken = await publicClient.readContract({
        address: addr,
        abi: STRATEGY_ABI,
        functionName: 'token',
      });

      if (stratToken.toLow
...[truncated 4330 chars]
Remediation
View remediation

Remediation Suggestions

  1. Require on-chain registry validation before every asset-moving operation. Call isUserStrategy(walletAddress, strategyAddress) and reject the address unless it returns true.
  2. Validate ownership. Require owner() to equal the active wallet before granting any allowance or invoking deposit.
  3. Validate contract provenance. Confirm that the contract was deployed by an approved factory and that its runtime bytecode, proxy implementation, strategy type, and underlying token match trusted values.
  4. Do not treat local storage as an authority. Use the JSON file only as a cache or discovery hint. A local entry must never become an approval recipient until independently validated on-chain.
  5. Handle legitimate local-only deployments securely. If newly created strategies are temporarily absent from the registry, validate the factory transaction receipt and emitted deployment event, bind the resulting address to the expected owner and factory, and revalidate those properties before each deposit.
  6. Harden local file storage. Create ~/.config/mamo with mode 0700, create configuration files with mode 0600, use atomic replacement, reject symbolic links, and validate the parsed schema and Ethereum addresses.
  7. Fail closed. If registry, ownership, bytecode, or factory validation is unavailable, do not approve tokens or execute a deposit.
  8. Add regression tests. Include tests proving that a local contract with a matching token() response is rejected when registry membership, ownership, or trusted provenance cannot be established.
  9. Correct the documentation. Either implement the stated registry verification guarantee or clearly disclose the fallback trust model and its security limitations.
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (64)

Credential Access

High
Category
Privilege Escalation
Confidence
98% confidence
Finding

The documentation provides a concrete command that writes MAMO_WALLET_KEY directly into a .env file, normalizing plaintext storage of a blockchain private key. In this skill's context, that credential grants direct signing authority over on-chain assets, so exposure can immediately enable unauthorized withdrawals or malicious transactions.

Content

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

export MAMO_WALLET_KEY=0xYourPrivateKeyHere export MAMO_RPC_URL=https://mainnet.base.org

Option 2: .env file

echo "MAMO_WALLET_KEY=0xYourPrivateKeyHere" > .env

text

Credential Access

High
Category
Privilege Escalation
Confidence
97% confidence
Finding

This finding is part of the same .env-based secret handling guidance and reinforces a pattern of storing wallet credentials in plaintext local configuration. Because the CLI is designed to manage real funds on Base mainnet, the surrounding skill context makes credential exposure especially dangerous: the secret is not just an API token, but a private key controlling assets.

Content

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

export MAMO_RPC_URL=https://mainnet.base.org

Option 2: .env file

echo "MAMO_WALLET_KEY=0xYourPrivateKeyHere" > .env

text

## How It Works

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The manifest describes interaction with yield strategies but omits that the skill can create or deploy new on-chain strategy contracts, which is a materially different and riskier action. In a blockchain context, undocumented transaction types can mislead users into authorizing irreversible writes and gas expenditure they did not expect.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The manifest describes interaction with yield strategies but omits that the skill can create or deploy new on-chain strategy contracts, which is a materially different and riskier action. In a blockchain context, undocumented transaction types can mislead users into authorizing irreversible writes and gas expenditure they did not expect.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The manifest describes interaction with yield strategies but omits that the skill can create or deploy new on-chain strategy contracts, which is a materially different and riskier action. In a blockchain context, undocumented transaction types can mislead users into authorizing irreversible writes and gas expenditure they did not expect.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The manifest describes interaction with yield strategies but omits that the skill can create or deploy new on-chain strategy contracts, which is a materially different and riskier action. In a blockchain context, undocumented transaction types can mislead users into authorizing irreversible writes and gas expenditure they did not expect.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The manifest describes interaction with yield strategies but omits that the skill can create or deploy new on-chain strategy contracts, which is a materially different and riskier action. In a blockchain context, undocumented transaction types can mislead users into authorizing irreversible writes and gas expenditure they did not expect.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The manifest describes interaction with yield strategies but omits that the skill can create or deploy new on-chain strategy contracts, which is a materially different and riskier action. In a blockchain context, undocumented transaction types can mislead users into authorizing irreversible writes and gas expenditure they did not expect.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The manifest describes interaction with yield strategies but omits that the skill can create or deploy new on-chain strategy contracts, which is a materially different and riskier action. In a blockchain context, undocumented transaction types can mislead users into authorizing irreversible writes and gas expenditure they did not expect.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The manifest describes interaction with yield strategies but omits that the skill can create or deploy new on-chain strategy contracts, which is a materially different and riskier action. In a blockchain context, undocumented transaction types can mislead users into authorizing irreversible writes and gas expenditure they did not expect.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: brace-expansion==2.0.2 — 4 advisory(ies): CVE-2026-13149 (brace-expansion: DoS via exponential-time expansion of consecutive non-expanding); CVE-2026-33750 (brace-expansion: Zero-step sequence causes process hang and memory exhaustion); CVE-2026-14257 (brace-expansion: DoS via unbounded expansion length causing an out-of-memory pro) +1 more

High
Category
Supply Chain
Confidence
80% confidence
Finding

Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: minimatch==9.0.5 — 3 advisory(ies): CVE-2026-27904 (minimatch ReDoS: nested *() extglobs generate catastrophically backtracking regu); CVE-2026-26996 (minimatch has a ReDoS via repeated wildcards with non-matching literal in patter); CVE-2026-27903 (minimatch has ReDoS: matchOne() combinatorial backtracking via multiple non-adja)

High
Category
Supply Chain
Confidence
80% confidence
Finding

Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: brace-expansion==1.1.12 — 4 advisory(ies): CVE-2026-13149 (brace-expansion: DoS via exponential-time expansion of consecutive non-expanding); CVE-2026-33750 (brace-expansion: Zero-step sequence causes process hang and memory exhaustion); CVE-2026-14257 (brace-expansion: DoS via unbounded expansion length causing an out-of-memory pro) +1 more

High
Category
Supply Chain
Confidence
80% confidence
Finding

Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: flatted==3.3.3 — 2 advisory(ies): CVE-2026-32141 (flatted vulnerable to unbounded recursion DoS in parse() revive phase); CVE-2026-33228 (Prototype Pollution via parse() in NodeJS flatted)

High
Category
Supply Chain
Confidence
80% confidence
Finding

Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: js-yaml==4.1.1 — 4 advisory(ies): CVE-2026-84375 (js-yaml: maxTotalMergeKeys does not limit CPU use for empty merge sources); CVE-2026-59869 (js-yaml: YAML merge-key chains can force quadratic CPU consumption); GHSA-5p4m-2wfm-xmqj (JS-YAML: Quadratic CPU consumption in !!omap resolution (3.x and 4.x) — CVE-2026) +1 more

High
Category
Supply Chain
Confidence
80% confidence
Finding

Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: minimatch==3.1.2 — 3 advisory(ies): CVE-2026-27904 (minimatch ReDoS: nested *() extglobs generate catastrophically backtracking regu); CVE-2026-26996 (minimatch has a ReDoS via repeated wildcards with non-matching literal in patter); CVE-2026-27903 (minimatch has ReDoS: matchOne() combinatorial backtracking via multiple non-adja)

High
Category
Supply Chain
Confidence
80% confidence
Finding

Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: nanoid==3.3.11 — 3 advisory(ies): CVE-2026-67214 (nanoid: non-secure generators can loop indefinitely with negative size); CVE-2026-67213 (nanoid: custom generators can loop indefinitely when size is zero); CVE-2026-73086 (nanoid: Integer Overflow or Wraparound)

High
Category
Supply Chain
Confidence
80% confidence
Finding

Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: picomatch==2.3.1 — 2 advisory(ies): CVE-2026-33672 (Picomatch: Method Injection in POSIX Character Classes causes incorrect Glob Mat); CVE-2026-33671 (Picomatch has a ReDoS vulnerability via extglob quantifiers)

High
Category
Supply Chain
Confidence
80% confidence
Finding

Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: postcss==8.5.6 — 4 advisory(ies): CVE-2026-45623 (PostCSS: Arbitrary file read and information disclosure via attacker-controlled ); CVE-2026-69153 (PostCSS: incomplete fix of GHSA-6g55-p6wh-862q — attacker-controlled sourceMappi); CVE-2026-41305 (PostCSS has XSS via Unescaped </style> in its CSS Stringify Output) +1 more

High
Category
Supply Chain
Confidence
80% confidence
Finding

Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: rollup==4.57.1 — 1 advisory(ies): CVE-2026-27606 (Rollup 4 has Arbitrary File Write via Path Traversal)

High
Category
Supply Chain
Confidence
80% confidence
Finding

Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/mamo.mjs (reported line 16)May include surrounding context.

js
import { homedir } from 'os';
import { fileURLToPath } from 'url';

// Load .env from script directory
const __dirname = dirname(fileURLToPath(import.meta.url));
const envPath = join(__dirname, '.env');
if (existsSync(envPath)) {

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · src/index.ts (reported line 20)May include surrounding context.

ts
import { homedir } from 'os';
import { fileURLToPath } from 'url';

// Load .env from script directory
const __dirname = dirname(fileURLToPath(import.meta.url));
const envPath = join(__dirname, '.env');
if (existsSync(envPath)) {

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/mamo.mjs (reported line 18)May include surrounding context.

js
// Load .env from script directory
const __dirname = dirname(fileURLToPath(import.meta.url));
const envPath = join(__dirname, '.env');
if (existsSync(envPath)) {
  for (const line of readFileSync(envPath, 'utf-8').split('\n')) {
    const trimmed = line.trim();

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · src/index.ts (reported line 23)May include surrounding context.

ts
// Load .env from script directory
const __dirname = dirname(fileURLToPath(import.meta.url));
const envPath = join(__dirname, '.env');
if (existsSync(envPath)) {
  for (const line of readFileSync(envPath, 'utf-8').split('\n')) {
    const trimmed = line.trim();

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · src/index.ts (reported line 24)May include surrounding context.

ts
// Load .env from script directory
const __dirname = dirname(fileURLToPath(import.meta.url));
const envPath = join(__dirname, '.env');
if (existsSync(envPath)) {
  for (const line of readFileSync(envPath, 'utf-8').split('\n')) {
    const trimmed = line.trim();

Static analysis

Detected: suspicious.env_credential_access

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/mamo.mjs:27