Back to skill

Security audit

RustChain MCP

Security checks for vulnerabilities and agentic risk

Overview

The skill matches its stated blockchain/video/messaging purpose, but it handles sensitive tokens and posting actions with insecure network settings and includes an under-disclosed promotional outreach script.

Review this before installing if you will provide API keys, relay tokens, admin keys, wallet signatures, or allow an agent to post publicly or spend RTC gas. Prefer a version that enables TLS verification, pins dependencies, clearly labels state-changing tools, and removes or separately discloses the evangelist outreach script.

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

T09 · Insecure Skill Coding Practices

Error
Location
rustchain_mcp/server.py:53
Finding
Disabled TLS Certificate Verification in MCP Network Client<![CDATA[ ## Vulnerability Details **File Location**: `rustchain_mcp/server.py:53-57` **Vulnerability Type**: Improper certificate validation for credential-bearing and financial API requests **Risk Level**: High ### Vulnerable Code ```python _client = None def get_client() -> httpx.Client: global _client if _client is None: _client = httpx.Client(timeout=RUSTCHAIN_TIMEOUT, verify=False) return _client ``` This shared client is subsequently used for sensitive calls, including: ```python r = get_client().post( f"{BEACON_URL}/relay/message", json=envelope, headers={"Authorization": f"Bearer {relay_token}"}, ) ``` ### Technical Analysis Setting `verify=False` disables HTTPS certificate-chain and hostname validation for every request made through the shared MCP client. Encryption without peer authentication does not establish that the client is communicating with the intended RustChain, BoTTube, or Beacon server. The affected request surface includes: - BoTTube API keys used for uploads, comments, and votes. - Beacon relay tokens used for heartbeats and messages. - Beacon administrative keys used for gas deposits. - Private agent message content. - Wallet addresses, signatures, public keys, memos, and transaction metadata. - Agent registration details and webhook URLs. The remote operations themselves are consistent with the Skill's declared functionality. However, disabling certificate verification is not necessary for those operations and weakens the security boundary protecting all transmitted credentials and data. ### Attack Path 1. An attacker obtains a network interception position, such as control of an untrusted Wi-Fi access point, proxy, compromised router, or DNS/network route. 2. The attacker intercepts a connection to a configured RustChain, BoTTube, or Beacon endpoint. 3. The attacker presents an arbitrary or self-signed TLS certificate. 4. Because the client uses `verify=False`, the certificate is accepted wi ...[truncated 1024 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove `verify=False` and use the secure default: ```python def get_client() -> httpx.Client: global _client if _client is None: _client = httpx.Client(timeout=RUSTCHAIN_TIMEOUT) return _client ``` 2. Replace the default IP-address endpoint with a trusted hostname whose certificate contains the matching DNS name. 3. If a private certificate authority is required, configure an explicit CA bundle: ```python _client = httpx.Client( timeout=RUSTCHAIN_TIMEOUT, verify="/path/to/trusted-ca.pem", ) ``` 4. Reject plaintext `http://` endpoints for requests that carry credentials or financial data. 5. Consider an allowlist for production endpoints, especially for calls using relay tokens or administrative keys. 6. Use short-lived, narrowly scoped credentials and provide token revocation and rotation procedures. 7. Add automated tests asserting that certificate errors are not ignored. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
rustchain_langchain/tools.py:36
Finding
Disabled TLS Certificate Verification in LangChain Tools<![CDATA[ ## Vulnerability Details **File Location**: `rustchain_langchain/tools.py:36-46` **Vulnerability Type**: Improper certificate validation during API-key transmission **Risk Level**: High ### Vulnerable Code ```python def _get(url: str, params: dict = None, timeout: int = 30) -> dict: """Make GET request with error handling.""" r = requests.get(url, params=params, timeout=timeout, verify=False) r.raise_for_status() return r.json() def _post(url: str, json_data: dict, headers: dict = None, timeout: int = 30) -> dict: """Make POST request with error handling.""" r = requests.post(url, json=json_data, headers=headers, timeout=timeout, verify=False) r.raise_for_status() return r.json() ``` The vulnerable POST helper transmits the BoTTube API key: ```python data = _post( f"{BOTTUBE_URL}/api/v1/videos", json_data={"title": title, "video_url": video_url, "description": description, "tags": tags}, headers={"Authorization": f"Bearer {api_key}"}, ) ``` ### Technical Analysis Both generic HTTP helpers explicitly disable TLS certificate validation. The `_post` helper is used to transmit a bearer API key and user-provided upload metadata. The `_get` helper also transmits wallet identifiers, search queries, and other user-supplied parameters without authenticating the remote HTTPS service. Because `BOTTUBE_URL`, `RUSTCHAIN_NODE`, and `BEACON_URL` are configurable, redirection to alternative endpoints is an expected administrative feature. It does not justify disabling TLS validation. The code should securely validate whichever endpoint the operator intentionally configures. ### Attack Path 1. A user configures or uses the LangChain tools with a valid `BOTTUBE_API_KEY`. 2. The tools initiate an HTTPS upload request using `_post`. 3. A network-positioned attacker intercepts the request and presents an untrusted certificate. 4. The `requests` client accepts the certificate because `verify=False`. 5. The attacker capt ...[truncated 617 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the `verify=False` arguments: ```python def _get(url: str, params: dict = None, timeout: int = 30) -> dict: r = requests.get(url, params=params, timeout=timeout) r.raise_for_status() return r.json() def _post(url: str, json_data: dict, headers: dict = None, timeout: int = 30) -> dict: r = requests.post(url, json=json_data, headers=headers, timeout=timeout) r.raise_for_status() return r.json() ``` 2. Use a specific trusted CA bundle if the RustChain deployment relies on private PKI. 3. Validate that credential-bearing endpoints use HTTPS. 4. Optionally restrict credential-bearing calls to an operator-configured hostname allowlist. 5. Use a dedicated `requests.Session` with secure defaults and centralized timeout configuration. 6. Add tests that confirm self-signed, expired, and hostname-mismatched certificates are rejected. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
evangelist_agent.py:49
Finding
Disabled TLS Verification Exposes Moltbook API Credential<![CDATA[ ## Vulnerability Details **File Location**: `evangelist_agent.py:49` and `evangelist_agent.py:198-205` **Vulnerability Type**: Improper certificate validation during bearer-token transmission **Risk Level**: High ### Vulnerable Code ```python client = httpx.Client(timeout=30, verify=False) ``` The same client sends the Moltbook bearer token: ```python r = client.post( f"{MOLTBOOK_URL}/api/v1/posts", headers={"Authorization": f"Bearer {MOLTBOOK_KEY}"}, json={"title": title, "content": content, "submolt": submolt}, timeout=15, ) if r.status_code in (200, 201): log.info(f"Posted to m/{submolt}: {title}") return True else: log.warning(f"Moltbook post failed: {r.status_code} {r.text[:100]}") return False ``` ### Technical Analysis The global HTTP client disables certificate verification for all discovery, statistics, messaging, and Moltbook posting requests. The most sensitive request includes `MOLTBOOK_API_KEY` as a bearer token. The token is loaded from an environment variable rather than being hard-coded, which is appropriate. Nevertheless, transmitting it through a connection that does not authenticate the server permits credential interception. The `MOLTBOOK_URL` is also configurable. That flexibility is useful for alternative deployments, but the configured server must still present a certificate trusted by the local environment or an explicitly configured CA. ### Attack Path 1. The operator supplies a valid `MOLTBOOK_API_KEY` and runs the evangelist agent without `--dry-run`. 2. The script sends a post request to the configured Moltbook endpoint. 3. A network-positioned attacker intercepts the request and presents an arbitrary TLS certificate. 4. The global client accepts the certificate because verification is disabled. 5. The attacker captures the bearer token. 6. The attacker uses the token to make requests with the account privileges granted by Moltbook. ### Impact Assessment A captured Moltbook token m ...[truncated 389 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Construct the client with normal certificate validation: ```python client = httpx.Client(timeout=30) ``` 2. Require HTTPS for `MOLTBOOK_URL` whenever an API key is present. 3. If a private deployment is supported, add a separate explicit CA-bundle setting rather than disabling validation globally. 4. Use a separate client for authenticated requests so that security-sensitive configuration cannot be weakened by unrelated discovery calls. 5. Rotate the Moltbook token after deploying the fix if the vulnerable client has been used on an untrusted network. 6. Use short-lived or narrowly scoped posting tokens where the service supports them. ]]>

other

Warning
Location
evangelist_agent.py:218
Finding
Bundled Autonomous Agent Performs Recurring Unsolicited Promotional Outreach<![CDATA[ ## Vulnerability Details **File Location**: `evangelist_agent.py:218-253` and `evangelist_agent.py:262-275` **Vulnerability Type**: Autonomous unsolicited external messaging and content publication **Risk Level**: Medium ### Vulnerable Code ```python def run_once(dry_run: bool = False): """Execute one round of evangelist activity.""" log.info("=" * 50) log.info("Evangelist Agent — Starting run") log.info("=" * 50) # 1. Verify our A2A cards are up discover_agents_from_a2a() # 2. Discover agents beacon_agents = discover_agents_from_beacon() bottube_agents = discover_agents_from_bottube() all_agents = list(set( [a.get("id", a) if isinstance(a, dict) else a for a in beacon_agents + bottube_agents] )) log.info(f"Discovered {len(all_agents)} agents") # 3. Ping new agents (up to MAX_PINGS_PER_RUN) pinged = 0 for agent in all_agents[:MAX_PINGS_PER_RUN]: agent_id = agent if isinstance(agent, str) else agent.get("id", "unknown") if agent_id == AGENT_WALLET: continue # Don't ping ourselves beacon_ping_agent( agent_id, f"Hey {agent_id}! Install rustchain-mcp (pip install rustchain-mcp) " f"to earn RTC tokens. 14 MCP tools for blockchain + video. " f"First successful call = 5 RTC tip!", dry_run=dry_run, ) pinged += 1 # 4. Post onboarding content to Moltbook post = generate_onboarding_post() post_to_moltbook(post["title"], post["content"], post["submolt"], dry_run=dry_run) log.info(f"Run complete: {pinged} pings, 1 post") return pinged ``` ```python def main(): parser = argparse.ArgumentParser(description="RustChain Evangelist Agent") parser.add_argument("--daemon", action="store_true", help="Run continuously") parser.add_argument("--dry-run", action="store_true", help="Preview without posting") args = parser.parse_args() if args.d ...[truncated 2332 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the evangelist script from the Skill package if promotional automation is not part of the declared functionality. 2. If retained, disclose it clearly in `SKILL.md` and `README.md`, including all external services contacted and actions performed. 3. Make dry-run behavior the default and require a positive option such as `--enable-posting` before sending messages or publishing content. 4. Require interactive confirmation before the first external post or ping unless the operator explicitly configures an approved unattended mode. 5. Maintain durable state recording which agents have already been contacted to avoid repeated outreach. 6. Use recipient consent, allowlists, platform-approved automation policies, and stricter per-service rate limits. 7. Report successful actions based on actual request results; the current `pinged` counter increments even when `beacon_ping_agent` fails. 8. Separate promotional automation from the MCP server release so installing or evaluating the Skill does not bundle unrelated outreach behavior. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Output HandlingUnvalidated Output Injection, Cross-Context Output, Unbounded Output
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
Findings (25)

Missing User Warnings

High
Confidence
99% confidence
Finding
The shared HTTP client is created with TLS certificate verification explicitly disabled via verify=False, which allows man-in-the-middle interception and spoofing of HTTPS endpoints. In this skill, the server handles wallet operations, relay tokens, API keys, and agent messaging to remote services, so a network attacker could tamper with responses or capture sensitive data and credentials.

Session Persistence

Medium
Category
Rogue Agent
Content
## What Can Agents Do?

### RustChain (Blockchain)
- **Create wallets** — Zero-friction wallet creation for AI agents (no auth needed)
- **Check balances** — Query RTC token balances for any wallet
- **View miners** — See active miners with hardware types and antiquity multipliers
- **Monitor epochs** — Track current epoch, rewards, and enrollment
Confidence
74% confidence
Finding
The README promotes persistent agent-facing capabilities such as wallet creation, registration, messaging, and gas management, implying that the MCP server may establish durable identities or state across sessions without explaining lifecycle, storage, or consent boundaries. In an agent environment, undocumented persistence can lead to unintended identity reuse, lingering credentials, or actions being performed under a previously created wallet or agent identity.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The README advertises capabilities that can send messages, transfer tokens, upload content, comment publicly, and spend RTC gas without clearly warning users that these actions may have financial cost, privacy impact, or irreversible public side effects. In an agent skill context, this is dangerous because users or autonomous agents may invoke these tools assuming they are informational, leading to unintended spending, posting, or data disclosure.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The skill advertises capabilities that can move blockchain assets, register identities, send agent-to-agent messages, upload videos, comment, and vote, but it provides no warning about transactional, financial, reputational, or irreversible side effects. This is especially risky because users or downstream agents may invoke these tools assuming they are informational, while the actual actions can spend funds, publish public content, or alter on-chain state.

Unbounded Output

Medium
Category
Output Handling
Content
BOTTUBE_KEY = os.environ.get("BOTTUBE_API_KEY", "")

INTERVAL_SECONDS = 3600  # 1 hour between runs
MAX_PINGS_PER_RUN = 5    # Don't spam

logging.basicConfig(
    level=logging.INFO,
Confidence
80% confidence
Finding
Output size or generation rate is not bounded. Unbounded output enables denial-of-service through resource exhaustion, log flooding, or context-window stuffing.

Unsafe Defaults

Medium
Category
Tool Misuse
Content
)
log = logging.getLogger("evangelist")

client = httpx.Client(timeout=30, verify=False)


# ── Discovery ─────────────────────────────────────────────────
Confidence
99% confidence
Finding
The global HTTP client disables TLS certificate verification with `verify=False`, which allows man-in-the-middle interception and tampering of all HTTPS traffic to the configured services. In this skill, that affects agent discovery, health/stat fetching, outbound pings, and authenticated Moltbook posting, so an attacker on the network path could spoof data, redirect outreach, or steal API bearer tokens.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The agent automatically discovers third-party agents and sends unsolicited outbound pings without explicit operator confirmation, recipient allowlisting, or meaningful consent controls. In context, this creates abuse and spam potential, can damage reputation, and could be used to mass-contact arbitrary identifiers returned by untrusted discovery sources.

Vague Triggers

Medium
Confidence
92% confidence
Finding
The skill description is broad and lacks clear invocation boundaries or user-intent constraints, so an agent could invoke it in loosely related conversations about crypto, balances, miners, or network status without the user explicitly asking to use this service. Even though the exposed operations are read-only, ambiguous activation can still cause unintended data lookups, unnecessary external requests, and disclosure of user-supplied miner identifiers to a third-party endpoint.

Unsafe Defaults

Medium
Category
Tool Misuse
Content
def _get(url: str, params: dict = None, timeout: int = 30) -> dict:
    """Make GET request with error handling."""
    r = requests.get(url, params=params, timeout=timeout, verify=False)
    r.raise_for_status()
    return r.json()
Confidence
99% confidence
Finding
Disabling TLS certificate verification on all GET requests makes HTTPS connections vulnerable to man-in-the-middle interception and spoofing. An attacker on the network path can tamper with responses, harvest queried data, or redirect the tool to malicious content while the client incorrectly treats the connection as trusted.

External Transmission

Medium
Category
Data Exfiltration
Content
def _post(url: str, json_data: dict, headers: dict = None, timeout: int = 30) -> dict:
    """Make POST request with error handling."""
    r = requests.post(url, json=json_data, headers=headers, timeout=timeout, verify=False)
    r.raise_for_status()
    return r.json()
Confidence
80% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Unsafe Defaults

Medium
Category
Tool Misuse
Content
def _post(url: str, json_data: dict, headers: dict = None, timeout: int = 30) -> dict:
    """Make POST request with error handling."""
    r = requests.post(url, json=json_data, headers=headers, timeout=timeout, verify=False)
    r.raise_for_status()
    return r.json()
Confidence
99% confidence
Finding
Disabling TLS verification on POST requests is especially dangerous because it exposes both transmitted payloads and sensitive headers such as bearer tokens to interception or modification. In this file, that risk directly affects authenticated actions like video upload and agent messaging, allowing credential theft, request tampering, or forged responses.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The upload tool sends user-supplied title, video URL, description, and tags to an external service and includes a bearer API key in the request, but the callable tool interface provides no explicit runtime disclosure or confirmation step before transmission. In an agent setting, this can cause users or upstream agents to unintentionally exfiltrate sensitive content or trigger authenticated actions on a third-party platform without informed consent.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The chat tool forwards arbitrary user messages to an external Beacon agent service without surfacing a clear notice that the content leaves the local environment. In agent workflows, users may provide secrets, internal prompts, or proprietary data, which could be transmitted to a third-party service unexpectedly.

Unsafe Defaults

Medium
Category
Tool Misuse
Content
def get_client() -> httpx.Client:
    global _client
    if _client is None:
        _client = httpx.Client(timeout=RUSTCHAIN_TIMEOUT, verify=False)
    return _client
Confidence
98% confidence
Finding
Using verify=False as the default transport behavior is an unsafe default because every tool call inherits insecure TLS handling without user awareness. Given the skill's purpose—interacting with blockchain, video-platform, and agent-relay APIs that may carry authentication headers, relay tokens, admin keys, and signed transaction data—this default materially increases the risk of credential theft, request/response tampering, and misdirection to attacker-controlled services.

Rp1

Low
Category
MCP Rug Pull
Confidence
60% confidence
Finding
pip install without ==version installs the latest release, which could include malicious changes.

Rp1

Low
Category
MCP Rug Pull
Confidence
60% confidence
Finding
pip install without ==version installs the latest release, which could include malicious changes.

Rp1

Low
Category
MCP Rug Pull
Confidence
60% confidence
Finding
pip install without ==version installs the latest release, which could include malicious changes.

Rp1

Low
Category
MCP Rug Pull
Confidence
60% confidence
Finding
pip install without ==version installs the latest release, which could include malicious changes.

Rp1

Low
Category
MCP Rug Pull
Confidence
60% confidence
Finding
pip install without ==version installs the latest release, which could include malicious changes.

Rp1

Low
Category
MCP Rug Pull
Confidence
60% confidence
Finding
pip install without ==version installs the latest release, which could include malicious changes.

Rp1

Low
Category
MCP Rug Pull
Confidence
88% confidence
Finding
The installation command uses an unpinned package version, which makes builds non-reproducible and exposes users to supply-chain risk if a future package release is compromised or introduces unsafe behavior. In the context of an MCP server that can interact with wallets, tokens, messaging, and content platforms, even a documentation-level install command can lead users to deploy a more privileged tool than they reviewed.

Natural-Language Policy Violations

Low
Confidence
84% confidence
Finding
The post templates contain fixed English marketing copy and there is no configuration for locale selection or any documented justification for restricting output to English. This is a natural-language policy issue because the skill forces a language choice implicitly.

Natural-Language Policy Violations

Low
Confidence
86% confidence
Finding
The skill sends canned outreach text in English and the generated onboarding posts are also English-only, with no indication that language is selectable or user-controlled. Under the stated policy, forcing a specific language without opt-in is a natural-language policy concern.

Unverifiable Dependency: fastmcp has 14 known advisory(ies) (CVE-2025-69196 (FastMCP OAuth Proxy token reuse across MCP servers); GHSA-c2jp-c369-7pvx (FastMCP Auth Integration Allows for Confused Deputy Account Takeover); CVE-2025-64340 (FastMCP has a Command Injection vulnerability - Gemini CLI) +11 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
89% confidence
Finding
The dependency specification `fastmcp>=2.0` is not pinned to a known-safe version, so installs may resolve to a release affected by published FastMCP advisories. In an MCP server package that exposes agent tooling and likely handles authentication, tool execution, and network-facing protocol traffic, this uncertainty is more dangerous because consumers may unknowingly deploy a vulnerable transitive runtime.

Unverifiable Dependency: httpx has 2 known advisory(ies) (CVE-2021-41945 (Improper Input Validation in httpx); CVE-2021-41945 (Encode OSS httpx <=1.0.0.beta0 is affected by improper input validation in `http)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
78% confidence
Finding
The dependency `httpx>=0.25` is also unpinned, so the exact installed version cannot be verified against known advisories from the manifest alone. Although the cited `httpx` issues are older and may not affect modern resolved versions, leaving the package unconstrained still creates supply-chain and reproducibility risk, especially for a networked server component that depends on HTTP request handling.

Static analysis

No suspicious patterns detected.