Back to skill

Security audit

Conto Hermes

Security checks for vulnerabilities and agentic risk

Overview

The skill has a coherent payment-policy purpose, but it gives agents financial and policy-admin authority with weak safeguards around credential setup, storage, endpoint validation, destructive policy changes, and final fund transfers.

Review this carefully before installing, especially if you would use an admin SDK key or let the agent move funds. Prefer a standard payment-approval key, avoid admin policy commands from chat, confirm every transfer yourself, keep CONTO_API_URL fixed to the real HTTPS Conto endpoint, and secure or rotate any SDK key written to ~/.hermes/.env.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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 (5)

T09 · Insecure Skill Coding Practices

Error
Location
conto-check.sh:231
Finding

Python Code Injection Through the Agent Name

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
conto-check.sh:198
Finding

Unauthenticated Local Callback Allows SDK Credential Injection

Content
View full analysis
Setup Failed

' + error.encode() + b'

You can close this window.

') with open('${TMPFILE}', 'w') as f: json.dump({'error': error}, f) elif sdk_key: self.wfile.write(b'

Agent Connected!

You can close this window and return to your terminal.

') with open('${TMPFILE}', 'w') as f: json.dump({'sdkKey': sdk_key, 'agentId': agent_id, 'org': org}, f) else: self.wfile.write(b'

Setup Error

No SDK key received.

') with open('${TMPFILE}', 'w') as f: json.dump({'error': 'No SDK key in callback'}, f) threading.Thread(target=self.server.shutdown).start() def log_message(self, *a): pass server = http.server.HTTPServer(('127.0.0.1', ${CALLBACK_PORT}), Handler) server.timeout = 300 try: server.handle_request() except: pass " & ``` ### Technical Analysis The temporary callback server accepts the first HTTP GET request and trusts the `sdkKey`, `agentId`, and `org` query parameters without authenticating the response. There is no cryptographically random state value, callback nonce, exact-path validation, origin binding, authorization-code exchange, or signature verification. Binding to ...[truncated 1599 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
conto-check.sh:271
Finding

SDK Key Is Stored Without Enforcing Restrictive File Permissions

Content
View full analysis
"${HERMES_ENV}.tmp" || true mv "${HERMES_ENV}.tmp" "$HERMES_ENV" fi echo "CONTO_SDK_KEY=$SDK_KEY_VALUE" >> "$HERMES_ENV" echo "CONTO_API_URL=$API_URL" >> "$HERMES_ENV" ``` ### Technical Analysis The setup routine writes a bearer credential to a plaintext environment file but does not set a restrictive `umask`, directory mode, or file mode. Under a common `umask 022`, a newly created `.env` or `${HERMES_ENV}.tmp` can be created with mode `0644`, allowing other local users to read it. When an existing file is filtered into `${HERMES_ENV}.tmp` and moved over the original file, the replacement receives the temporary file's permissions rather than necessarily preserving the original file's secure mode. Consequently, an existing mode-`0600` credential file can be replaced by a more permissive file. The fixed temporary filename also provides weaker safety than a securely created, unpredictable temporary file. ### Attack Path 1. The user runs setup with a permissive process `umask`. 2. The script creates or replaces `~/.hermes/.env` without explicitly setting its permissions. 3. The resulting file is readable by other local accounts. 4. Another local user reads `CONTO_SDK_KEY` from the file. 5. The stolen bearer credential is used against the Conto API. 6. If the credential is an admin key, the attacker can additionally create, modify, or delete spending policies. ### Impact Assessment Exposure of a standard key can permit unauthorized policy checks, payment confirmations, access to ...[truncated 327 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
conto-check.sh:27
Finding

Configurable API URL Can Exfiltrate Bearer Credentials or Forge Policy Responses

Content
View full analysis
` and ...[truncated 731 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
README.md:220
Finding

Unpinned npx Dependency Executes Mutable Remote Package Code

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
Findings (25)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The declared description frames the skill as a payment policy checker, but the content also provisions agents, opens browser-based setup flows, stores SDK keys in ~/.hermes/.env, manages policies, and drives payment execution/confirmation. This mismatch can mislead users and reviewers about the real trust boundary and authority of the skill, increasing the chance that powerful wallet and credential operations are approved without informed consent.

Content

No source excerpt is available for this finding.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% confidence
Finding

The delete-policy operation interpolates an externally supplied policy_id directly into a privileged DELETE request, with no allowlisting, authorization narrowing, or secondary confirmation. In an agent setting, this enables parameter abuse: if the agent is induced to pass an attacker-chosen identifier while holding an admin key, it can delete arbitrary policies and disable spending protections.

Content

Scanner excerpt · conto-check.sh (reported line 149)May include surrounding context.

sh
delete-policy)
    policy_id="${2:?policy_id required}"
    _conto_request DELETE "/api/policies/$policy_id"
    ;;

  get-rules)

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% confidence
Finding

The delete-rule operation directly embeds user-controlled policy_id and rule_id values into a destructive API path and executes immediately. In this context, an agent with admin credentials could be manipulated into deleting targeted protective rules, creating subtle policy bypasses that facilitate unauthorized payments while being harder to notice than full policy deletion.

Content

Scanner excerpt · conto-check.sh (reported line 172)May include surrounding context.

sh
delete-rule)
    policy_id="${2:?policy_id required}"
    rule_id="${3:?rule_id required}"
    _conto_request DELETE "/api/policies/$policy_id/rules/$rule_id"
    ;;

  setup)

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 · conto-check.sh (reported line 271)May include surrounding context.

sh
exit 1
    fi

    # Write to ~/.hermes/.env
    HERMES_ENV="$HOME/.hermes/.env"
    mkdir -p "$(dirname "$HERMES_ENV")"

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 · conto-check.sh (reported line 275)May include surrounding context.

sh
exit 1
    fi

    # Write to ~/.hermes/.env
    HERMES_ENV="$HOME/.hermes/.env"
    mkdir -p "$(dirname "$HERMES_ENV")"

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 · conto-check.sh (reported line 272)May include surrounding context.

sh
fi

    # Write to ~/.hermes/.env
    HERMES_ENV="$HOME/.hermes/.env"
    mkdir -p "$(dirname "$HERMES_ENV")"

    # Update or append CONTO_SDK_KEY and CONTO_API_URL in .env

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 13)May include surrounding context.

md
### 1. Sign up and install

Create an account at [conto.finance](https://conto.finance).

Install the skill from the well-known endpoint:

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The README says the skill activates automatically when users mention policies or payments naturally, which is overly broad for a wallet-controlling agent. In this context, ambiguous or incidental conversation can trigger policy-management or payment-related actions unintentionally, increasing the risk of prompt-triggered financial operations or sensitive state changes.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
88% confidence
Finding

The README instructs users to run npx tsx ... without pinning a specific package version. This makes the execution path depend on whatever version is resolved at runtime, which can change unexpectedly or be influenced by a compromised upstream package, leading to arbitrary code execution during testing.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill clearly expects shell, network, and local file-write capabilities but does not declare tool scope or allowed tools. That weakens least-privilege controls and can cause the agent runtime to grant broader capabilities than users expect, especially because the skill also persists credentials and performs payment-related API calls.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% confidence
Finding

The mention of auto-execution in the mode comparison indicates the skill supports flows where approval directly leads to execution by a custody provider. Even if this is descriptive rather than imperative, it normalizes autonomous payment execution and increases risk when users may not realize a single API call can move funds.

Content

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

md
| Question                        | Mode A                                                     | Mode B                                              |
| ------------------------------- | ---------------------------------------------------------- | --------------------------------------------------- |
| Who holds the wallet keys?      | Custody provider (Privy or Sponge)                         | You (via Hermes/Sponge MCP tools)                   |
| How many API calls per payment? | 1 (single call, auto-executes)                             | 3 (approve → transfer → confirm)                    |
| When to use?                    | Wallet `custodyType` is PRIVY or SPONGE in Conto dashboard | Wallet `custodyType` is EXTERNAL in Conto dashboard |

**Most Hermes setups use Mode B** — your agent controls the wallet via Sponge MCP tools and Conto acts as the policy gate before each transaction.

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 146)May include surrounding context.

For wallets managed by a custody provider (Privy or Sponge), use a single API call. Conto evaluates policies and instructs the custody provider to execute the transfer.

bash
curl -sS -X POST "${CONTO_API_URL:-https://conto.finance}/api/sdk/payments/request" \
  -H "Authorization: Bearer $CONTO_SDK_KEY" \
  -H "Content-Type: application/json" \
  --connect-timeout 10 --max-time 30 \

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
95% confidence
Finding

Setting 'autoExecute': true in the payment request allows the external service/custody path to execute a payment immediately after policy approval. That creates a one-step money movement path controlled by the skill and remote service, which is risky if the initiating request is mistaken, prompt-injected, or insufficiently verified.

Content

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

"recipientName": "<OPTIONAL_NAME>", "purpose": "<WHY_THIS_PAYMENT>", "category": "", "autoExecute": true }'

text

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
90% confidence
Finding

The reference to autoExecuteError handling still directs the agent to continue execution autonomously through a fallback API call. Fallback automation is especially dangerous because it can bypass a natural pause that would otherwise let a user notice and stop an unintended payment.

Content

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

No need to call /execute or /confirm — Conto did everything. Report the tx hash and explorer URL to the user.

If approved but not auto-executed (e.g., autoExecuteError in response), call /execute manually:

bash
curl -sS -X POST "${CONTO_API_URL:-https://conto.finance}/api/sdk/payments/<REQUEST_ID>/execute" \

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
90% confidence
Finding

The reference to autoExecuteError handling still directs the agent to continue execution autonomously through a fallback API call. Fallback automation is especially dangerous because it can bypass a natural pause that would otherwise let a user notice and stop an unintended payment.

Content

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

No need to call /execute or /confirm — Conto did everything. Report the tx hash and explorer URL to the user.

If approved but not auto-executed (e.g., autoExecuteError in response), call /execute manually:

bash
curl -sS -X POST "${CONTO_API_URL:-https://conto.finance}/api/sdk/payments/<REQUEST_ID>/execute" \

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
97% confidence
Finding

The instruction 'Do NOT ask the user to execute it' explicitly removes the user from the final fund-transfer decision and enables autonomous movement of wallet assets. In a payment skill, that context makes autonomous action especially dangerous because transactions are often irreversible and financially impactful.

Content

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

md
### Step 2a: Execute the Transfer

**Now execute the payment using your wallet.** Conto approved the policy — now YOU must send the actual onchain transaction. Do NOT ask the user to execute it.

Use the appropriate MCP tool for the target chain:

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill instructs the agent to execute a blockchain transfer after policy approval without requiring a fresh explicit user confirmation at the moment funds move. Policy approval is not equivalent to user intent verification, so a prompt-injected or mistaken request could still result in irreversible loss of funds.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
88% confidence
Finding

The critical rules explicitly codify autoExecute as a normal supported payment pattern, embedding autonomous asset movement into the skill's core operating model. Because this is a financial skill, normalizing no-confirmation execution materially increases the consequences of misuse or prompt manipulation.

Content

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

md
## Critical Rules

1. **Use the right mode for the wallet type.** Mode A (`/request` + `autoExecute`) for PRIVY/SPONGE wallets. Mode B (`/approve` + transfer + `/confirm`) for EXTERNAL wallets.
2. **NEVER skip the policy check.** Every payment must go through Conto first.
3. **NEVER execute a denied payment.** If `approved` is `false` or `status` is `DENIED`, stop.
4. **For Mode B: ALWAYS confirm after execution.** Call `/confirm` with the tx hash to keep spend tracking accurate. Mode A handles this automatically.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill is presented as a payment-policy enforcement helper, but it also exposes agent setup and full policy administration operations, including create, update, and delete actions. This capability mismatch increases the chance that an agent or user invokes high-privilege behavior under the assumption that the tool only performs pre-payment checks, which can lead to unauthorized policy changes and weakened spending controls.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The script includes destructive administrative endpoints that can delete policies, replace all rules, and remove individual rules, which are powerful actions for a tool whose stated purpose is enforcing spending policies before payments. If an agent with access to an admin SDK key can invoke these commands, it could disable or rewrite controls that are supposed to protect funds, enabling subsequent unauthorized spending.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The delete-policy command performs an irreversible destructive action immediately with no user confirmation, preview, or safeguard. In the context of a spending-policy tool, accidental or coerced invocation can remove financial controls and leave wallets unprotected until policies are restored.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The delete-rule command deletes individual policy rules without confirmation or validation, which can silently weaken a policy while leaving the policy object itself in place. That makes the change easy to overlook and dangerous in this context because removing a single deny or limit rule may effectively bypass intended spending restrictions.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
80% confidence
Finding

The script intentionally establishes session persistence by saving the SDK key under ~/.hermes/.env, allowing future commands to authenticate without repeating setup. In this financial-policy context, persistent credentials materially increase the blast radius of host compromise or accidental reuse because they may grant ongoing authority over approvals or policy administration.

Content

Scanner excerpt · conto-check.sh (reported line 271)May include surrounding context.

sh
exit 1
    fi

    # Write to ~/.hermes/.env
    HERMES_ENV="$HOME/.hermes/.env"
    mkdir -p "$(dirname "$HERMES_ENV")"

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The setup flow persists the received SDK key to ~/.hermes/.env automatically, without an explicit warning, opt-in, or file-permission hardening. Persisting API credentials silently increases the risk of unintended long-term exposure to other local processes, users, backups, or later agent actions that read the environment file.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
77% confidence
Finding

The README instructs users to ask the agent for its wallet address and notes that a wallet may be auto-provisioned, but it does not include an explicit privacy/safety warning. In a financial-agent context, exposing wallet addresses can aid profiling and targeted attacks, and silent or unclear wallet provisioning can surprise users about custody and onchain traceability.

Content

No source excerpt is available for this finding.