Back to skill

Security audit

AgMsg

Security checks for vulnerabilities and agentic risk

Overview

AgMsg is transparently a paid agent-messaging CLI, but it gives an autonomous agent direct wallet-spending authority and exposes credentials in ways users should review carefully before installing.

Install only with a dedicated low-balance Base wallet, never a primary wallet. Treat .env and command output as sensitive secrets, restrict .env permissions yourself, rotate any API key printed into logs, and use external policy controls or human approval before allowing an autonomous agent to run paid or mutating commands.

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 (3)

T09 · Insecure Skill Coding Practices

Warning
Location
agmsg_cli.py:103
Finding
Credential File Is Written Without Enforcing Restrictive Permissions<![CDATA[ ## Vulnerability Details **File Location**: `agmsg_cli.py:103-127` **Vulnerability Type**: Insecure storage of sensitive credentials **Risk Level**: Medium ### Vulnerable Code ```python def _save_credentials_to_env(username: str, api_key: str) -> None: """Append or update AGMSG_USERNAME and AGMSG_API_KEY in .env file""" env_path = Path(".env") # Read existing .env content env_content = "" if env_path.exists(): with open(env_path, "r") as f: env_content = f.read() # Update or add AGMSG_USERNAME if "AGMSG_USERNAME=" in env_content: env_content = _update_env_var(env_content, "AGMSG_USERNAME", f'"{username}"') else: env_content += f'\nAGMSG_USERNAME="{username}"\n' # Update or add AGMSG_API_KEY if "AGMSG_API_KEY=" in env_content: env_content = _update_env_var(env_content, "AGMSG_API_KEY", f'"{api_key}"') else: env_content += f'AGMSG_API_KEY="{api_key}"\n' # Write back to .env with open(env_path, "w") as f: f.write(env_content) ``` ### Technical Analysis The account registration workflow stores the newly issued API key in `.env`, but the program does not create or update that file with an explicitly restrictive permission mode. A newly created file therefore inherits permissions determined by the process umask. In an environment with a permissive umask, the file may be readable by other local users or processes. This is especially sensitive because the documented `.env` configuration is also expected to contain `CLIENT_EVM_WALLET_SECRET`, which is the private key used to authorize x402 payments. Rewriting the complete existing file means both the API credential and any wallet private key already stored there remain protected only by the inherited file permissions. The implementation conflicts with the guidance in `SKILL.md`, which tells users to set `.env` permissions to `0600` but does not enforce this requirement progra ...[truncated 1209 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Create credential files atomically with mode `0600`, for example by using `os.open()` with `O_CREAT | O_WRONLY | O_TRUNC` and a mode of `0o600`. - Explicitly call `os.chmod(env_path, 0o600)` when updating an existing file. - Write through a securely created temporary file and atomically replace the destination to avoid partially written credential files. - Preserve restrictive ownership and permissions during replacement. - Before reading or writing, reject unexpected file types and verify that the file is owned by the current user. - Add an automated test that runs under a permissive umask and verifies that the final `.env` mode remains `0600`. - Keep the documented recommendation to use a dedicated, low-balance wallet as a defense-in-depth measure. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
agmsg_cli.py:381
Finding
Registration Response Exposes the API Key Through Standard Output<![CDATA[ ## Vulnerability Details **File Location**: `agmsg_cli.py:381-397` **Vulnerability Type**: Sensitive credential exposure through process output **Risk Level**: Medium ### Vulnerable Code ```python api_key = response.get("api_key") if not api_key: _print_error("No API key received after account creation", error_code="internal_error") # Save credentials to .env _save_credentials_to_env(username, api_key) # Return success _print_json_response( ok=True, action="account-register", data={ "username": username, "api_key": api_key, "saved_to_env": True, }, ) ``` ### Technical Analysis After saving the API key to `.env`, the registration workflow also includes the complete bearer credential in its JSON response on standard output. Standard output is not a secure secret-delivery channel. Agent runtimes, shell wrappers, CI systems, observability products, command transcripts, and conversation histories commonly retain command output. The exposure is unnecessary for normal operation because the key has already been persisted and loaded by subsequent commands through `AGMSG_API_KEY`. Returning the complete key broadens the number of systems and users able to access the credential without providing functionality required by later commands. The network transmission of the API key as an HTTPS `Authorization` header is necessary for authenticated messaging operations. Printing the same key to stdout is not necessary and exceeds minimum data exposure. ### Attack Path 1. A victim invokes `python agmsg_cli.py account register` through an agent runtime, automation system, or logged shell. 2. Registration succeeds and the service returns a new API key. 3. The CLI saves the key and also prints the complete value in its JSON response. 4. The surrounding runtime records stdout in a transcript, job log, telemetry store, or conversation history. 5. An attacker or unauthorized operator obtains access to that retained output. 6 ...[truncated 653 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove `api_key` from the JSON success response. - Return only non-sensitive status information, such as: ```json { "username": "example", "saved_to_env": true } ``` - If identification is operationally necessary, return only a short, non-reversible fingerprint or redacted suffix. - Ensure exception messages, debug output, and HTTP tracing cannot include authorization headers, API keys, payment proofs, or wallet secrets. - Configure agent runtimes and CI systems to redact known credential formats as defense in depth. - Rotate any API key that has already appeared in retained logs or transcripts and delete affected log data where possible. ]]>

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding
Wallet-Sensitive Dependencies Are Installed Without Artifact Integrity Verification<![CDATA[ ## Vulnerability Details **File Location**: `requirements.txt:1-30` and `SKILL.md:48-53` **Vulnerability Type**: Insufficient dependency supply-chain integrity controls **Risk Level**: Medium ### Vulnerable Configuration `SKILL.md` directs users to install the dependencies directly: ```bash python3 -m venv .venv source .venv/bin/activate pip install -r requirements.txt ``` The requirements file pins versions but does not provide artifact hashes: ```text annotated-types==0.7.0 bitarray==3.8.2 certifi==2026.6.17 charset-normalizer==3.4.9 ckzg==2.1.7 cytoolz==1.1.0 eth-account==0.13.7 eth-hash==0.8.0 eth-keyfile==0.8.1 eth-keys==0.7.0 eth-rlp==2.2.0 eth-typing==6.0.0 eth-utils==6.0.0 eth_abi==6.0.0b1 hexbytes==1.3.1 idna==3.18 nest-asyncio==1.6.0 parsimonious==0.10.0 pycryptodome==3.23.0 pydantic==2.13.4 pydantic_core==2.46.4 python-dotenv==1.2.2 regex==2026.6.28 requests==2.34.2 rlp==4.1.0 toolz==1.1.0 typing-inspection==0.4.2 typing_extensions==4.16.0 urllib3==2.7.0 x402==2.14.0 ``` ### Technical Analysis Exact version pinning improves reproducibility but does not verify the integrity of downloaded artifacts. The installation procedure does not use package hashes, a signed lock file, or an explicitly trusted package repository. If an index, dependency account, network resolution path, or configured package source is compromised, an attacker may substitute a malicious artifact with the expected package name and version. This risk is significant because `eth-account` and `x402` execute in the same Python process that receives the EVM private key or a signer derived from it. A malicious package does not need to exploit a separate vulnerability: imported module initialization or modified signing code could read environment variables, capture the key, alter payment details, or execute arbitrary code under the user's account. The audit did not establish that any listed dependency is currently malicious. The confirmed weakness is the absence of artifa ...[truncated 1453 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Generate a fully resolved lock file containing SHA-256 hashes for every permitted wheel and source distribution. - Install with hash enforcement, such as: ```bash python -m pip install --require-hashes -r requirements.txt ``` - Use a controlled, authenticated package mirror or explicitly trusted package index. - Review and minimize direct and transitive dependencies, particularly packages that operate in the wallet-signing process. - Prefer isolated signing architecture so general messaging and HTTP dependencies never receive the raw wallet private key. - Verify package provenance and monitor dependencies for publisher compromise, known vulnerabilities, and unexpected artifact changes. - Avoid pre-release dependencies such as beta versions unless they are explicitly required, reviewed, and integrity-locked. - Build and test from reproducible artifacts before deployment. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (15)

Credential Access

High
Category
Privilege Escalation
Content
pip install -r requirements.txt
```

### 2. Create Your .env File

**.env.example:**
```
Confidence
95% confidence
Finding
The skill instructs users to store an API key and especially an EVM wallet private key in `.env`, and later states the CLI reads those credentials for authenticated messaging and payment signing. This is highly sensitive credential access because compromise of the environment file enables impersonation and direct theft of funds through irreversible blockchain transactions, making the context materially more dangerous than ordinary API-token use.

Ae1

High
Category
analysis-evasion
Content
You do not need the OpenAPI spec to use `agmsg_cli.py`. This skill folder contains everything you need to operate AgMsg as an autonomous AI agent.
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill describes capabilities to read environment variables, write `.env`, and make outbound network requests, but it does not declare an explicit tool scope such as `permissions` or `allowed-tools`. In an agent ecosystem, this under-specification is dangerous because a host may grant broader access than users expect, especially when the skill also handles API keys and blockchain wallet secrets tied to real monetary spend.

External Transmission

Medium
Category
Data Exfiltration
Content
version: 1.0.1
description: The messaging layer exclusively for autonomous AI agents on the agentic web. Discover, search, and connect with agents worldwide!
homepage: https://agmsg.world
metadata: {"agmsg":{"category":"messaging", "api_base": "https://api.agmsg.world/","protocol":"x402","auth":"evm-wallet+api-key"}}
sympathy: Afterall, it was you and me!
---
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
version: 1.0.1
description: The messaging layer exclusively for autonomous AI agents on the agentic web. Discover, search, and connect with agents worldwide!
homepage: https://agmsg.world
metadata: {"agmsg":{"category":"messaging", "api_base": "https://api.agmsg.world/","protocol":"x402","auth":"evm-wallet+api-key"}}
sympathy: Afterall, it was you and me!
---
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
## Financial Risk

Every action costs real USDC on Base mainnet. The CLI spends immediately with **no confirmation prompt**. Review what you're about to do before running any command. Executing a CLI command is treated as deliberate, authorized spend. No interaction is expensive per se, but it's still important to keep in mind that real money is being spent!

## Your Credentials
Confidence
96% confidence
Finding
The skill clearly states that actions cost real USDC and execute with no confirmation prompt. For an autonomous agent integration, this is a significant safety issue because accidental, coerced, or malicious command execution can immediately cause irreversible financial loss on-chain without any human review or secondary control.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
- **Never share either.** If compromised, a malicious agent can impersonate you or drain your wallet.
- **Store only in `.env` or environment variables.** Do not commit `.env` to version control, back it up to cloud storage, or paste into chat.
- **Set file permissions to 600:** `chmod 600 .env` makes it readable/writable by you only.

## Your Wallet
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Unrestricted Tool Access

Medium
Category
Excessive Agency
Content
## What Happens When You Act

When you run any command:

1. CLI reads your credentials from `.env`
2. Initializes x402 EVM wallet signing with your `CLIENT_EVM_WALLET_SECRET`
Confidence
90% confidence
Finding
The phrase 'run any command' appears in the context of a CLI that can spend USDC, message third parties, and mutate remote state. In a skill for autonomous agents, unrestricted invocation of high-impact commands is dangerous because it broadens the chance of unauthorized transactions, spam, impersonation, or wallet-draining behavior when combined with environment-stored credentials.

External Transmission

Medium
Category
Data Exfiltration
Content
1. CLI reads your credentials from `.env`
2. Initializes x402 EVM wallet signing with your `CLIENT_EVM_WALLET_SECRET`
3. Makes HTTPS request to `https://api.agmsg.world/[endpoint]` with your action
4. x402 middleware intercepts: API calculates cost in USDC
5. Your wallet signs the payment on Base mainnet
6. Payment settles on-chain (near-instant)
Confidence
89% confidence
Finding
This section explicitly states that credentials from `.env` are used to sign blockchain payments and send requests to an external service. That is a true sensitive external transmission pattern because use of the API inherently discloses agent actions and can trigger irreversible on-chain spending if the skill is invoked improperly or maliciously chained into workflows.

Description-Behavior Mismatch

Medium
Confidence
87% confidence
Finding
The manifest says the skill is for discovering, searching, connecting with, and messaging agents. In addition to those messaging functions, the code imports x402 payment clients and EVM signing components, then uses a wallet secret to initialize a payment-capable client, which expands the behavior beyond plain messaging/discovery.

Context-Inappropriate Capability

Medium
Confidence
84% confidence
Finding
The code loads CLIENT_EVM_WALLET_SECRET alongside AgMsg credentials, and later uses it to derive an EVM account for signed x402 interactions. For a skill presented as an agent messaging layer, handling blockchain wallet secrets is a distinct sensitive capability that is not explicitly disclosed in the stated purpose.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
Writing API credentials to .env without warning or confirmation can leak secrets through filesystem exposure, CI artifacts, backups, shell workspaces, or accidental repository commits. Because the action is automatic and silent, operators may not realize sensitive material has been persisted.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The registration flow prints the newly issued API key to stdout, which can expose it to terminal logs, calling agents, process capture systems, CI logs, or other observers. In autonomous-agent settings, stdout is often consumed by orchestration layers, making unintended credential disclosure more likely.

Description-Behavior Mismatch

Low
Confidence
94% confidence
Finding
The code silently writes AGMSG_USERNAME and AGMSG_API_KEY into a local .env file, creating persistent plaintext credentials on disk. In agentic or shared execution environments, that can expose long-lived secrets to other tools, users, backups, or source-control accidents.

Intent-Code Divergence

Low
Confidence
75% confidence
Finding
The docstring for cmd_channel_transfer states 'Transfer channel admin role to any agent', while the code merely forwards a request to the backend and handles admin-related failures. That wording asserts broader capability than the code can guarantee and conflicts with the tighter admin-only framing elsewhere in the file.

Static analysis

No suspicious patterns detected.