Back to skill

Security audit

Trustra Escrow

Security checks for vulnerabilities and agentic risk

Overview

This escrow skill appears purpose-aligned overall, but it handles real funds and wallet secrets with weak safeguards that users should review carefully.

Install only if you are comfortable giving this skill authority over a Trustra managed wallet and escrow funds. Treat credentials.json, terminal transcripts, and export_key.py output as highly sensitive; avoid running private-key export in logged agent sessions, restrict file permissions, and require manual review before any command that pays, releases, withdraws, or exports wallet material.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/config.py:44
Finding

API Credentials Are Stored Without Enforced Owner-Only Permissions

Content
View full analysis
bool: """Save credentials to credentials.json file.""" try: with open(CREDS_FILE, "w") as f: json.dump(creds, f, indent=2) return True except IOError as e: print(f"Failed to save credentials: {e}", file=sys.stderr) return False ``` ### Technical Analysis The application writes `credentials.json` using the default permissions determined by the process umask. It does not explicitly enforce owner-only permissions such as `0600`. According to `register.py`, this file contains a Trustra API key. That key is accepted by endpoints that initiate escrow payments, release funds, withdraw funds, cancel escrows, and export the managed wallet's private key. Consequently, it must be treated as a high-value financial credential. Although `.gitignore` excludes `credentials.json` from normal Git operations, that does not protect it from other local users, backup systems, accidental file copying, or processes running under different accounts. On a shared host with a permissive umask, the file may be group-readable or world-readable. ### Attack Path 1. A victim registers an agent, causing `save_credentials()` to create `credentials.json`. 2. The host uses a permissive umask or otherwise exposes the project directory to another local account. 3. An attacker with local filesystem access reads `credentials.json`. 4. The attacker extracts the `api_key`. 5. The attacker authenticates to the Trustra API using the stolen key. 6. Depending on the wallet and escrow state, the attacker invokes financial endpoints or calls `/wallet/export` to retrieve the wallet private key. 7. Retrieval of the private key can result in complete control over assets held by the managed wallet. ### Impact Assessment Succ ...[truncated 453 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/register.py:80
Finding

Registration Prints the Financial API Key to Standard Output

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/export_key.py:41
Finding

Wallet Private Key Is Printed in Plaintext to Standard Output

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
scripts/requirements.txt:1
Finding

Open-Ended Dependency Version Prevents Reproducible Installation

Content
View full analysis
=2.28.0 ``` ### Technical Analysis The project permits any `requests` release from version 2.28.0 onward. This means two installations performed at different times may resolve to different code. No lock file or package hashes are provided to verify the exact artifacts installed. No malicious dependency was identified in the audited project, and `requests` is the expected package rather than an apparent typosquat. The risk arises from allowing future, unaudited versions and transitive dependency changes to enter the execution environment automatically. Because `requests` processes the Trustra API key and private-key export response, compromise of this dependency or its dependency chain would affect highly sensitive data. ### Attack Path 1. A user installs dependencies using `pip install -r scripts/requirements.txt`. 2. The package resolver selects the newest version satisfying `requests>=2.28.0` and resolves its transitive dependencies. 3. A future compromised, malicious, or unexpectedly incompatible release is selected. 4. The affected dependency executes in the same Python process as the Skill. 5. It can access request headers, API responses, environment variables, and local files available to that process. 6. Sensitive credentials or wallet material may be disclosed or requests may be manipulated. ### Impact Assessment A compromised dependency executes with the same operating-system privileges as the Skill. It could read `credentials.json`, capture the Trustra API key, intercept the exported private key, alter financial API requests, or modify local files accessible to the process. This is a supply-chain hardening weakness rather than evidence that the currently declared package is malicious. ]]>
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (35)

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · .gitignore (reported line 2)May include surrounding context.

text
# Credentials
credentials.json

# Python
__pycache__/

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 · .gitignore (reported line 19)May include surrounding context.

text
# Virtual environments
venv/
env/
.env

# IDE
.idea/

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The documented purpose is escrow payments, but the skill also exposes export_key.py, which is a private-key extraction capability outside the core escrow workflow. A feature that exports wallet keys materially changes the trust model: anyone invoking it or any compromised agent using it could seize full control of funds, defeating the supposed safety of managed escrow.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
91% confidence
Finding

The skill stores an API key and wallet address in credentials.json, indicating local credential material is written to disk. In an agent environment with file access, such credentials can be leaked, copied, or mishandled, enabling unauthorized payment actions or account takeover if protections are weak.

Content

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

python register.py --name "My Agent"

text

Creates a managed wallet + API key stored in `credentials.json`. Fund wallet with SOL (for tx fees) and USDC to use escrows.

## Errors

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · scripts/config.py (reported line 18)May include surrounding context.

python
# Paths
SKILL_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
CREDS_FILE = os.path.join(SKILL_DIR, "credentials.json")

# API URL
BASE_URL = "https://api.trustra.xyz/api/v2"

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · scripts/config.py (reported line 33)May include surrounding context.

python
# Paths
SKILL_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
CREDS_FILE = os.path.join(SKILL_DIR, "credentials.json")

# API URL
BASE_URL = "https://api.trustra.xyz/api/v2"

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · scripts/config.py (reported line 57)May include surrounding context.

python
# Paths
SKILL_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
CREDS_FILE = os.path.join(SKILL_DIR, "credentials.json")

# API URL
BASE_URL = "https://api.trustra.xyz/api/v2"

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · scripts/config.py (reported line 61)May include surrounding context.

python
# Paths
SKILL_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
CREDS_FILE = os.path.join(SKILL_DIR, "credentials.json")

# API URL
BASE_URL = "https://api.trustra.xyz/api/v2"

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · scripts/config.py (reported line 97)May include surrounding context.

python
# Paths
SKILL_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
CREDS_FILE = os.path.join(SKILL_DIR, "credentials.json")

# API URL
BASE_URL = "https://api.trustra.xyz/api/v2"

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · scripts/config.py (reported line 115)May include surrounding context.

python
# Paths
SKILL_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
CREDS_FILE = os.path.join(SKILL_DIR, "credentials.json")

# API URL
BASE_URL = "https://api.trustra.xyz/api/v2"

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · scripts/register.py (reported line 51)May include surrounding context.

python
# Paths
SKILL_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
CREDS_FILE = os.path.join(SKILL_DIR, "credentials.json")

# API URL
BASE_URL = "https://api.trustra.xyz/api/v2"

Credential Access

High
Category
Privilege Escalation
Confidence
95% confidence
Finding

This code writes the entire credentials structure to credentials.json in plaintext, creating a clear local secret-exposure risk. Any API key, wallet metadata, or agent information stored there may be disclosed through repo inclusion, backups, malware, or other local-user access.

Content

Scanner excerpt · scripts/config.py (reported line 45)May include surrounding context.

python
def save_credentials(creds: dict) -> bool:
    """Save credentials to credentials.json file."""
    try:
        with open(CREDS_FILE, "w") as f:
            json.dump(creds, f, indent=2)

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · scripts/config.py (reported line 57)May include surrounding context.

python
def get_api_key(required: bool = True) -> str | None:
    """
    Get API key from credentials.json or environment.
    
    Priority:
    1. TRUSTRA_API_KEY environment variable

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

This script provides a direct private-key export capability for a managed wallet, which is highly sensitive functionality and materially exceeds the stated escrow-focused purpose of the skill. In an agent setting, any capability that reveals raw private key material can immediately lead to irreversible theft of all wallet assets and complete loss of account control.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
94% confidence
Finding

The script prints the newly issued API key directly to stdout after registration. Secrets echoed to terminal output can be captured in shell history, logs, CI/CD job output, terminal recording tools, or remote session transcripts, increasing the chance of credential compromise in an automation-focused agent environment.

Content

Scanner excerpt · scripts/register.py (reported line 78)May include surrounding context.

python
print(f"Agent ID: {agent.get('id')}")
        print(f"Wallet: {agent.get('walletAddress')}")
        print("")
        print("API Key saved to credentials.json")
        print("")
        print("IMPORTANT: Back up your API key. It will not be shown again.")
        print(f"API Key: {result.get('apiKey')}")

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill advertises commands that inherently need filesystem, credential, and network access, but it does not declare any explicit tool scope or permissions boundaries. In an agent setting, this increases the chance of over-broad execution privileges and makes it harder for operators to review or sandbox sensitive capabilities like credential storage and payment actions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The instructions direct users to create, fund, confirm, dispute, and withdraw escrowed funds, but they do not clearly warn that these actions move real assets and may be irreversible once submitted on-chain or released from escrow. In a payments skill, missing transaction-risk warnings makes accidental loss more likely, especially for autonomous or semi-autonomous agents.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The quick reference includes python export_key.py with no adjacent warning that exporting a wallet key exposes complete control over the wallet and any funds it holds. In this context, the omission is especially dangerous because the skill manages payment wallets, so key export is effectively equivalent to handing over ownership of assets.

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

md
CREDS_FILE = os.path.join(SKILL_DIR, "credentials.json")

# API URL
BASE_URL = "https://api.trustra.xyz/api/v2"

# Solana RPC
RPC_URL = "https://api.mainnet-beta.solana.com"  # Production

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 · scripts/config.py (reported line 21)May include surrounding context.

python
CREDS_FILE = os.path.join(SKILL_DIR, "credentials.json")

# API URL
BASE_URL = "https://api.trustra.xyz/api/v2"

# Solana RPC
RPC_URL = "https://api.mainnet-beta.solana.com"  # Production

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The code persists credentials to a project-local JSON file in plaintext without setting restrictive permissions, encryption, or warning the user that secrets will be stored on disk. If the working directory is shared, committed, backed up, or readable by other local users/processes, the API key and wallet-related data could be exposed.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The script performs an irreversible withdrawal by sending {"execute": true} immediately after parsing a user-supplied escrow ID, with no confirmation prompt, dry-run mode, or explicit warning about the finality of the action. In an agent or automation context, this increases the risk of accidental or mis-targeted withdrawals if the wrong escrow ID is supplied or the script is invoked unintentionally.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The docstring describes the action as simple wallet portability, but the code actually retrieves and prints the full private key. This framing downplays the sensitivity of the operation, increasing the chance that users or agents invoke it without understanding that they are exposing the wallet's root secret.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
87% confidence
Finding

The outbound POST itself is not inherently malicious, but in this context it triggers server-side export of private key material and returns that secret to the client. Because the response is then exposed by the script, this network action is part of a sensitive secret-extraction flow that can leak credentials to the agent runtime, logs, terminals, or downstream tooling.

Content

Scanner excerpt · scripts/export_key.py (reported line 20)May include surrounding context.

python
url = f"{BASE_URL}/wallet/export"
    headers = get_headers(api_key)
    
    response = requests.post(url, json={}, headers=headers)
    
    if response.status_code == 200:
        return response.json()

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% 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 · scripts/escrow_cancel.py (reported line 28)May include surrounding context.

python
if email:
        payload["email"] = email
    
    response = requests.post(url, json=payload, headers=HEADERS)
    
    if response.status_code == 201:
        return response.json()

Static analysis

No suspicious patterns detected.