Back to skill

Security audit

tmrland-business-demo

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent TMR Land business-management integration, but it handles high-impact account, wallet, contract, KYC, and API-key operations with some under-scoped credential and secret-handling safeguards.

Review this skill carefully before installing. Use a narrowly scoped TMR_API_KEY, avoid setting TMR_BASE_URL unless you fully trust the endpoint, and do not enter passwords or government identity numbers directly in shell commands on shared or logged systems. High-impact marketplace actions are disclosed, but they can affect contracts, orders, wallet balances, public reputation, and API-key access.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/_lib.mjs:6
Finding
Unrestricted API Base URL Can Exfiltrate Bearer Credentials and Sensitive Request Data## Vulnerability Details **File Location**: `scripts/_lib.mjs:6-7, 38-50`; `scripts/upload-file.mjs:6-7, 15-25` **Vulnerability Type**: Arbitrary authenticated request destination **Risk Level**: High ### Vulnerable Code `scripts/_lib.mjs:6-7, 38-50` ```js const API_KEY = (process.env.TMR_API_KEY ?? "").trim(); const BASE_URL = (process.env.TMR_BASE_URL ?? "https://tmrland.com/api/v1").replace(/\/$/, ""); export async function tmrFetchSafe(method, path, body = null) { const url = `${BASE_URL}${path}`; const opts = { method, headers: { "Authorization": `Bearer ${API_KEY}`, "Content-Type": "application/json", }, }; if (body !== null) { opts.body = JSON.stringify(body); } const resp = await fetch(url, opts); ``` `scripts/upload-file.mjs:6-7, 15-25` ```js const API_KEY = (process.env.TMR_API_KEY ?? "").trim(); const BASE_URL = (process.env.TMR_BASE_URL ?? "https://tmrland.com/api/v1").replace(/\/$/, ""); const filePath = positional[0]; const fileName = basename(filePath); const fileData = readFileSync(filePath); const formData = new FormData(); formData.append("file", new Blob([fileData]), fileName); const resp = await fetch(`${BASE_URL}/uploads/`, { method: "POST", headers: { "Authorization": `Bearer ${API_KEY}` }, body: formData, }); ``` ### Technical Analysis The destination of every authenticated API request is controlled by the `TMR_BASE_URL` environment variable. The code does not validate the URL scheme, hostname, port, embedded credentials, or origin before attaching `TMR_API_KEY` as a bearer credential. Consequently, any process or configuration source capable of setting this environment variable can redirect requests to an attacker-controlled server. The issue applies to all scripts using `tmrFetch` and to `upload-file.mjs`, which implements the same unsafe destination logic independently. Sensitive request bodies rou ...[truncated 2245 chars]
Remediation
## Remediation Suggestions 1. Default to the fixed production origin `https://tmrland.com` and reject other origins unless custom deployment support is explicitly enabled. 2. Parse the configured value with `new URL()` and enforce: - The `https:` scheme. - An explicit allowlist of trusted hostnames. - Expected ports. - No embedded username or password. - An expected API path prefix. 3. Use separate credentials for custom deployments. Never send a production TMR Land key to a user-supplied origin. 4. Reject credential-bearing redirects or configure requests for manual redirect handling. Revalidate every redirect target before following it. 5. Centralize upload requests in the validated HTTP client instead of duplicating base URL and credential logic. 6. Add startup diagnostics that display the selected hostname without printing credentials and require explicit user confirmation for non-production endpoints. 7. Apply narrowly scoped API-key permissions so compromise of one key does not expose unrelated wallet, account, and administrative operations. 8. Add automated tests confirming that HTTP URLs, unapproved hosts, embedded credentials, unexpected ports, and cross-origin redirects are rejected.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/change-password.mjs:4
Finding
Passwords and Government Identity Data Are Exposed Through Command-Line Arguments## Vulnerability Details **File Location**: `scripts/change-password.mjs:4-12`; `scripts/submit-kyc.mjs:4-13`; `SKILL.md:165-166` **Vulnerability Type**: Sensitive information exposure through process arguments and shell history **Risk Level**: Medium ### Vulnerable Code `scripts/change-password.mjs:4-12` ```js const { help, named } = parseArgs(process.argv); if (help || !named.current || !named.new) { console.error("Usage: change-password.mjs --current <password> --new <password>"); process.exit(2); } await tmrFetch("PATCH", "/users/me/password", { current_password: named.current, new_password: named.new, }); ``` `scripts/submit-kyc.mjs:4-13` ```js const { help, named } = parseArgs(process.argv); if (help || !named.name || !named["id-type"] || !named["id-number"]) { console.error("Usage: submit-kyc.mjs --name \"...\" --id-type passport|national_id|driver_license --id-number \"...\""); process.exit(2); } const body = { name: named.name, id_type: named["id-type"], id_number: named["id-number"], }; ``` `SKILL.md:165-166` ```bash # Change password node {baseDir}/scripts/change-password.mjs --current <password> --new <password> ``` ### Technical Analysis The scripts obtain passwords and KYC identity values directly from `process.argv`. Command-line arguments are not an appropriate secret-input mechanism because they can be exposed through: - Shell command history. - Process inspection utilities while the command is running. - Process accounting and endpoint monitoring. - CI/CD logs and debugging traces. - Wrapper scripts or automation logs that record full commands. The documentation explicitly encourages users to place both the current and new password on the command line. `submit-kyc.mjs` similarly requires the user's legal name and identity number as arguments. Transmitting these values to the documented authenticated API e ...[truncated 1439 chars]
Remediation
## Remediation Suggestions 1. Read passwords from a hidden interactive prompt that disables terminal echo. 2. Support protected standard input for non-interactive automation rather than password command-line flags. 3. Avoid storing secrets in ordinary environment variables when a secure secret descriptor, operating-system keychain, or secret manager is available. 4. Remove password values from documented command examples and warn users not to place credentials in shell arguments. 5. Accept KYC data through an interactive prompt, protected standard input, or a permission-restricted input file. 6. Validate that KYC input files are regular files, are owned by the invoking user where supported, and do not have group/world-readable permissions. 7. Ensure errors, debug output, telemetry, and HTTP logs redact passwords, identity numbers, bearer keys, and related sensitive fields. 8. Clear in-memory references to sensitive argument values as soon as practical, while recognizing that this does not remove copies retained by the operating system or shell.
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (87)

Ae1

High
Category
analysis-evasion
Content
7. **Fulfill orders** — After deal acceptance, submit deliverables via `submit-delivery.mjs`
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Tool Parameter Abuse

High
Category
Tool Misuse
Content
---

## DELETE /api/v1/api-keys/{key_id}

Revoke and delete an API key. Only the key owner can delete.
Confidence
80% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
### Request Example

```
DELETE /api/v1/api-keys/key00002-2222-3333-4444-555566667777
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
```
Confidence
80% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
---

## DELETE /api/v1/contract-templates/{template_id}

Delete a contract template. Only the template owner can delete.
Confidence
80% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
### Request Example

```
DELETE /api/v1/contract-templates/d4e5f6a7-b8c9-0123-defa-234567890123
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
```
Confidence
80% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Missing User Warnings

High
Confidence
95% confidence
Finding
The `accept` endpoint explicitly creates a contract and order, which is a high-impact action affecting user commitments and system state, but the documentation does not include any caution or confirmation warning. For markdown skill/docs files, such impactful behavior should be clearly disclosed so users understand they are initiating a binding workflow transition.

Credential Access

High
Category
Privilege Escalation
Content
| Status | Code | Description |
|---|---|---|
| 401 | `not_authenticated` | Missing or invalid access token |

---
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
| Status | Code | Description |
|---|---|---|
| 401 | `not_authenticated` | Missing or invalid access token |

---
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
| Status | Code | Description |
|---|---|---|
| 401 | `not_authenticated` | Missing or invalid access token |

---
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
| Status | Code | Description |
|---|---|---|
| 401 | `not_authenticated` | Missing or invalid access token |

---
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
| Status | Code | Description |
|---|---|---|
| 401 | `not_authenticated` | Missing or invalid access token |

---
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
| Status | Code | Description |
|---|---|---|
| 401 | `not_authenticated` | Missing or invalid access token |

---
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
| Status | Code | Description |
|---|---|---|
| 401 | `not_authenticated` | Missing or invalid access token |

---
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
| Status | Code | Description |
|---|---|---|
| 401 | `not_authenticated` | Missing or invalid access token |

---
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
| Status | Code | Description |
|---|---|---|
| 401 | `not_authenticated` | Missing or invalid access token |

---
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
| Status | Code | Description |
|---|---|---|
| 401 | `not_authenticated` | Missing or invalid access token |

---
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
| Status | Code | Description |
|---|---|---|
| 401 | `not_authenticated` | Missing or invalid access token |

---
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
| Status | Code | Description |
|---|---|---|
| 401 | `not_authenticated` | Missing or invalid access token |

---
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
| Status | Code | Description |
|---|---|---|
| 401 | `not_authenticated` | Missing or invalid access token |

---
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
| Status | Code | Description |
|---|---|---|
| 401 | `not_authenticated` | Missing or invalid access token |

---
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
| Status | Code | Description |
|---|---|---|
| 401 | `not_authenticated` | Missing or invalid access token |

---
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
| Status | Code | Description |
|---|---|---|
| 401 | `not_authenticated` | Missing or invalid access token |

---
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
| Status | Code | Description |
|---|---|---|
| 401 | `not_authenticated` | Missing or invalid access token |

---
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
| Status | Code | Description |
|---|---|---|
| 401 | `not_authenticated` | Missing or invalid access token |

---
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
| Status | Code | Description |
|---|---|---|
| 401 | `not_authenticated` | Missing or invalid access token |

---
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Static analysis

Detected: suspicious.env_credential_access, suspicious.exposed_secret_literal

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/_lib.mjs:6

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/upload-file.mjs:6

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
references/api-keys-api.md:123

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
references/apparatus-api.md:365

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
references/businesses-api.md:23

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
references/contracts-api.md:93

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
references/error-codes.md:268

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
references/messages-api.md:23

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
references/notifications-api.md:27

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
references/user-api.md:23

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
references/wallet-api.md:25