Back to skill

Security audit

Trading Bot Fleet Management: Unified Control for Multi-Bot Operations

Security checks for vulnerabilities and agentic risk

Overview

This non-executable guide is purpose-aligned, but its trading-bot examples include unsafe high-impact control, authorization, and key-management patterns that should be reviewed before use.

Treat this as a review-required guide, not copy-paste production code. Before installing or using it, require real approval enforcement for permission changes, redesign key storage and rotation around a secrets manager or KMS with remote identity confirmation, separate sandbox and production credentials, and add explicit confirmation/dry-run policies for emergency stop and market-close actions.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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

Error
Location
SKILL.md:560
Finding

Private signing keys are returned and stored as Base64-encoded plaintext

Content
View full analysis
Tuple[str, str]: """Generate an Ed25519 keypair for a bot. Returns (public_key_b64, private_key_b64). """ signing_key = nacl.signing.SigningKey.generate() verify_key = signing_key.verify_key private_b64 = base64.b64encode( signing_key.encode() ).decode("utf-8") public_b64 = base64.b64encode( verify_key.encode() ).decode("utf-8") # Store private key securely -- in production, use a secrets manager key_path = os.path.join(self.key_store_path, f"{bot_name}.key") os.makedirs(os.path.dirname(key_path), exist_ok=True) with open(key_path, "w") as f: f.write(private_b64) os.chmod(key_path, 0o600) # Owner read/write only return public_b64, private_b64 ``` ### Technical Analysis Base64 is a reversible encoding and provides no confidentiality. The Ed25519 private key is therefore written to disk as plaintext-equivalent data. Although mode `0600` limits access to the owning account, it does not protect the key from privileged processes, compromise of that account, filesystem snapshots, backups, accidental file copying, or insecure container volume handling. The method also returns the private key to its caller. This unnecessarily expands the number of components that can access or accidentally log the key. The caller shown elsewhere in the guide does not require the private key value for registration, because only the public key is submitted to the remote identity service. The static pre-scan warning about encoding sensitive data is confirmed. However, this specific code does not transmit the encoded private key to an external endpoint, so a covert exfiltration channel was not established. The confirmed issue is i ...[truncated 1292 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
SKILL.md:1019
Finding

Permission escalation trusts an unauthenticated approver string

Content
View full analysis
{new_tier.value} (reason: {reason})") ``` ### Technical Analysis The method claims to require explicit approval, but `approved_by` is merely a caller-supplied string included in an audit event. The code does not authenticate the approver, verify a signature or approval token, check an authorization role, enforce separation of duties, or constrain allowed tier transitions. Consequently, any caller that can invoke this method can claim an arbitrary approver identity and assign any defined permission ...[truncated 1755 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:649
Finding

Key rotation changes local state without updating the registered public identity

Content
View full analysis
dict: """Rotate a bot's Ed25519 keypair without downtime. The rotation procedure: 1. Generate new keypair 2. Update GreenHelix identity with new public key 3. Bot continues operating -- it picks up the new key on next heartbeat 4. Old key is archived (not deleted) for signature verification of historical events """ if agent_id not in self.identities: raise ValueError(f"No identity record for {agent_id}") record = self.identities[agent_id] bot_name = record["bot_name"] # Archive old key old_key_path = os.path.join( self.key_store_path, f"{bot_name}.key.v{record['key_version']}" ) current_key_path = os.path.join( self.key_store_path, f"{bot_name}.key" ) if os.path.exists(current_key_path): os.rename(current_key_path, old_key_path) # Generate new keypair new_public, new_private = self.generate_keypair(bot_name) # Update the identity on GreenHelix -- submit metrics indicating rotation execute("submit_metrics", { "agent_id": agent_id, "metrics": { "key_rotation": 1, "key_version": record["key_version"] + 1, "rotation_timestamp": datetime.utcnow().isoformat() } }) # Notify the bot to pick up the new key execute("send_message", { "from_agent_id": self.fleet_manager_id, "to_agent_id": agent_id, "message_type": "command", "payload": { "command": "rotate_key", "new_public_key": new_public, "key_version": record["key_version"] + 1, "effective_at": datetime.utcnow().isoformat() } }) record["public_key"] = new_public re ...[truncated 2252 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (8)

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The rotation procedure claims to update the registered identity's public key, but the implementation only submits metrics and sends a message, leaving the authoritative remote identity unchanged. This can break authentication assumptions, create stale trust bindings, and cause operators to believe a compromised key has been replaced when the platform may still trust the old key.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The guide explicitly says the sandbox requires no API key, but the code samples configure bearer-token authorization and elsewhere point to the production API host. That mismatch can mislead operators into sending real credentials or live trading-control requests when they believe they are only experimenting in a harmless sandbox.

Content

No source excerpt is available for this finding.

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

md
from typing import Dict, List, Optional
from dataclasses import dataclass, field

base_url = "https://api.greenhelix.net/v1"
api_key = "your-api-key"  # From GreenHelix dashboard

session = requests.Session()

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

md
from typing import Dict, List, Optional
from dataclasses import dataclass, field

base_url = "https://api.greenhelix.net/v1"
api_key = "your-api-key"  # From GreenHelix dashboard

session = requests.Session()

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

return resp.json()

text

Equivalent curl for any `execute` call throughout this guide:

```bash
curl -X POST https://sandbox.greenhelix.net/v1 \

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The guide provides fleet-wide emergency-stop behavior that includes canceling orders and market-closing positions, but it does not prominently warn that these actions can realize losses, move size into thin markets, or be irreversible. In a trading context, understated destructive controls increase the risk of accidental mass liquidation by users copying the pattern without safeguards.

Content

No source excerpt is available for this finding.

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

bash
# curl: Submit bot heartbeat metrics
curl -X POST https://sandbox.greenhelix.net/v1 \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The documentation promises automatic pausing for critical SLA violations, but the code only emits alerts and events. Operators may rely on a nonexistent safety control, allowing a malfunctioning or runaway trading bot to continue operating during severe drawdown or latency breaches.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.