Back to skill

Security audit

EVC Team Relay

Security checks for vulnerabilities and agentic risk

Overview

This skill does what it says, but it gives an agent powerful read, write, and delete access to shared Obsidian notes with weak safeguards around credentials and destructive actions.

Install only for a trusted agent account with the minimum Relay permissions needed. Prefer a dedicated least-privilege account, use HTTPS-only RELAY_CP_URL values, avoid passing tokens as script arguments, keep backups/versioning for shared vaults, and require human approval before write or delete operations.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/write.sh:35
Finding
Bearer Token Disclosed in Error Output<![CDATA[ ## Vulnerability Details **File Location**: `scripts/write.sh:35-47` **Vulnerability Type**: Sensitive credential exposure through diagnostic output **Risk Level**: Medium ### Vulnerable Code ```bash if [ "$SHARE_ID" = "$DOC_ID" ]; then # Check if this is a folder share by trying to list files FILES_CHECK=$(curl -sf "${RELAY_CP_URL}/v1/documents/${SHARE_ID}/files?share_id=${SHARE_ID}" \ -H "Authorization: Bearer $TOKEN" 2>/dev/null || echo "") if [ -n "$FILES_CHECK" ]; then FILE_COUNT=$(echo "$FILES_CHECK" | jq '.files | length' 2>/dev/null || echo "0") if [ "$FILE_COUNT" -gt "0" ] || echo "$FILES_CHECK" | jq -e '.files' >/dev/null 2>&1; then echo "Error: this looks like a folder share (has file metadata)." >&2 echo "write.sh does NOT work for folder shares — files won't appear in Obsidian." >&2 echo "" >&2 echo "Use upsert-file.sh instead:" >&2 echo " scripts/upsert-file.sh \"$TOKEN\" \"$SHARE_ID\" \"filename.md\" \"content\"" >&2 exit 1 ``` ### Technical Analysis When `write.sh` determines that the supplied identifier appears to represent a folder share, it constructs a usage example containing the complete value of `$TOKEN` and writes it to standard error. Standard error is not a secure secret channel. It may be retained in AI agent transcripts, CI/CD logs, centralized logging systems, terminal recordings, support bundles, or command-execution audit trails. The exposed value is a bearer credential, so possession of it is sufficient to authenticate as the corresponding Relay user until the token expires or is revoked. ### Attack Path 1. A user or agent invokes `write.sh` with identical folder share and document identifiers. 2. The script successfully queries the folder’s file metadata. 3. The folder-share detection branch is entered. 4. The script prints a command containing the complete bearer token to standard error. 5. A local user, log reader, monitoring service, or other party with ...[truncated 816 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Never place authentication credentials in diagnostics, usage examples, or error messages. Replace the token-bearing output with an invocation that relies on the existing environment variable: ```bash echo "Use upsert-file.sh instead:" >&2 echo " scripts/upsert-file.sh \"$SHARE_ID\" \"filename.md\" \"content\"" >&2 ``` Additional hardening measures: 1. Search all script output paths to ensure that `$TOKEN`, `$RELAY_PASSWORD`, and complete API responses containing credentials are never printed. 2. Add automated tests that invoke error branches using a sentinel token and fail if the sentinel appears in stdout or stderr. 3. Treat existing logs as potentially compromised and remove any retained output containing tokens. 4. Revoke exposed tokens where supported, or wait for expiration before considering affected sessions secure. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
README.md:119
Finding
Bearer Tokens Passed Through Process Command-Line Arguments<![CDATA[ ## Vulnerability Details **File Location**: `README.md:119-131` **Additional Affected Locations**: `scripts/create-file.sh:15-20`, `scripts/delete-file.sh:13-18`, `scripts/list-files.sh:12-17`, `scripts/list-shares.sh:12-17`, `scripts/read-file.sh:16-21`, `scripts/read.sh:14-19`, `scripts/upsert-file.sh:19-24`, `scripts/write.sh:20-25` **Vulnerability Type**: Bearer credential exposure through process arguments **Risk Level**: Medium ### Vulnerable Documentation ```bash # Authenticate TOKEN=$(bash scripts/auth.sh) # List shared folders bash scripts/list-shares.sh "$TOKEN" # List files in a folder bash scripts/list-files.sh "$TOKEN" "<share_id>" # Read a note bash scripts/read.sh "$TOKEN" "<share_id>" "<doc_id>" # Write a note echo "# Hello from my agent" | bash scripts/write.sh "$TOKEN" "<share_id>" "<doc_id>" - ``` The operational scripts implement this fallback pattern. For example, `scripts/read.sh:14-19` contains: ```bash # Token: prefer RELAY_TOKEN env var, fall back to $1 (backward-compatible) if [ -n "${RELAY_TOKEN:-}" ]; then TOKEN="$RELAY_TOKEN" else TOKEN="${1:?Usage: read.sh [token] <share_id> [doc_id] [key] (or set RELAY_TOKEN)}" shift fi ``` ### Technical Analysis The README explicitly recommends passing the bearer token as the first positional argument. Every operational script supports the same backward-compatible behavior. When the shell expands `"$TOKEN"`, the credential becomes part of the child process argument vector. Process arguments may be exposed through process inspection interfaces, command-execution telemetry, endpoint monitoring, audit systems, debugging tools, and process launch records. Quoting the token prevents shell word splitting but does not prevent argument-vector disclosure. This documentation also conflicts with the safer recommendation in `SKILL.md`, which advises using `RELAY_TOKEN` because command-line tokens can be visible in process listings. ### Attack Path 1. A user follows the README ...[truncated 1269 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Remove the positional token interface and require `RELAY_TOKEN` through the environment or another protected credential mechanism. Update documentation to use: ```bash export RELAY_TOKEN="$(bash scripts/auth.sh)" bash scripts/list-shares.sh bash scripts/list-files.sh "<share_id>" bash scripts/read.sh "<share_id>" "<doc_id>" echo "# Hello from my agent" | bash scripts/write.sh "<share_id>" "<doc_id>" - ``` Update each affected script to reject a missing environment variable rather than interpreting `$1` as a token: ```bash : "${RELAY_TOKEN:?Set RELAY_TOKEN using scripts/auth.sh}" TOKEN="$RELAY_TOKEN" ``` Further hardening should include: 1. Remove all examples that place a real token in a command line. 2. If immediate removal would break compatibility, deprecate positional tokens, emit a warning that does not include the token, and remove support in the next major release. 3. Use a short-lived, least-privilege Relay account dedicated to the agent. 4. Avoid enabling shell tracing while handling credentials. 5. Add tests that verify documented invocations do not include tokens in positional arguments. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/auth.sh:8
Finding
Authentication Credentials Can Be Sent Over Plaintext HTTP<![CDATA[ ## Vulnerability Details **File Location**: `scripts/auth.sh:8-14` **Related Locations**: `README.md:63-71`, `SKILL.md:99-105` **Vulnerability Type**: Missing HTTPS enforcement for sensitive authentication traffic **Risk Level**: Medium ### Vulnerable Code ```bash : "${RELAY_CP_URL:?Set RELAY_CP_URL (e.g. https://cp.tr.entire.vc)}" : "${RELAY_EMAIL:?Set RELAY_EMAIL}" : "${RELAY_PASSWORD:?Set RELAY_PASSWORD}" resp=$(curl -sf -X POST "${RELAY_CP_URL}/v1/auth/login" \ -H "Content-Type: application/json" \ -d "{\"email\": \"${RELAY_EMAIL}\", \"password\": \"${RELAY_PASSWORD}\"}") ``` ### Technical Analysis `RELAY_CP_URL` is fully configurable, and `auth.sh` checks only that it is nonempty. Although the examples use HTTPS, the implementation accepts an `http://` endpoint without warning or rejection. If HTTP is configured, the login request sends the Relay email and password without transport encryption. Subsequent scripts also send bearer tokens and document contents to the same base URL. An attacker with a suitable network position can observe or alter this traffic. Because the password is a reusable account credential rather than only a short-lived token, interception of the login request may provide access beyond the lifetime of a single JWT. ### Attack Path 1. A user mistakenly configures `RELAY_CP_URL` with an `http://` URL, or an attacker influences the skill configuration. 2. `auth.sh` submits the user’s email and password in a plaintext HTTP request. 3. A network-positioned attacker captures the request. 4. The attacker extracts the reusable Relay credentials. 5. The attacker authenticates directly to the Relay service and obtains fresh tokens. 6. The attacker uses those tokens to access or modify shares available to the victim. 7. If subsequent API calls also use HTTP, the attacker can additionally capture bearer tokens, document data, or tamper with responses. ### Impact Assessment Successful interception can compromise both re ...[truncated 542 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Require HTTPS before transmitting credentials: ```bash : "${RELAY_CP_URL:?Set RELAY_CP_URL}" : "${RELAY_EMAIL:?Set RELAY_EMAIL}" : "${RELAY_PASSWORD:?Set RELAY_PASSWORD}" case "$RELAY_CP_URL" in https://*) ;; *) echo "Error: RELAY_CP_URL must use HTTPS" >&2 exit 1 ;; esac ``` Apply equivalent validation to every script, preferably through a shared helper to avoid inconsistent enforcement. Additional hardening measures: 1. Permit plaintext HTTP only through an explicit development override. 2. If a development override is required, restrict it to loopback destinations such as `127.0.0.1`, `localhost`, or `::1`. 3. Document HTTPS as mandatory rather than merely showing it in examples. 4. Use certificates issued by a trusted internal or public certificate authority. 5. Do not add `curl --insecure`, because disabling certificate verification would reintroduce interception risk. 6. Rotate the Relay password and revoke active sessions if credentials may previously have traversed plaintext HTTP. ]]>
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
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
Findings (22)

Ae1

High
Category
analysis-evasion
Content
scripts/delete-file.sh <folder_share_id> "old-note.md"
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
scripts/delete-file.sh <folder_share_id> "old-note.md"
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
scripts/delete-file.sh <folder_share_id> "old-note.md"
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Credential Access

High
Category
Privilege Escalation
Content
### POST /v1/auth/refresh

Refresh an expired access token.

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

Tool Parameter Abuse

High
Category
Tool Misuse
Content
- `422` — missing required fields
- `502` — relay server unavailable

### DELETE /v1/documents/{doc_id}/files/{file_path}

Delete a file from a folder share. Removes the entry from `filemeta_v0` Y.Map.
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).

Credential Access

High
Category
Privilege Escalation
Content
#!/usr/bin/env bash
# Authenticate with Relay Control Plane and print the access token.
# Usage: scripts/auth.sh
# Env: RELAY_CP_URL, RELAY_EMAIL, RELAY_PASSWORD
# Output: access_token (plain text, no newline) — suitable for $()
Confidence
85% confidence
Finding
The script prints the access token in plain text to stdout for command substitution. In a collaborative agent skill context, this is sensitive because tokens can be captured by logs, error reporting, shell tracing, parent processes, or other tooling integrations, potentially granting access to shared Relay/Obsidian data.

Session Persistence

Medium
Category
Rogue Agent
Content
[![OpenClaw](https://img.shields.io/badge/OpenClaw-skill-FF5A2D)](https://github.com/openclaw/openclaw)
[![Entire VC](https://img.shields.io/badge/Entire_VC-toolbox-525769)](https://entire.vc)

**Give your AI agent read/write access to your Obsidian vault.**

> Your agent reads your notes, creates new ones, and stays in sync — all through the Team Relay API.
Confidence
60% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The README explicitly markets broad read/write/delete access to a shared Obsidian vault but does not warn users about the risk of unintended modification, deletion, or exposure of sensitive team notes. In an agent skill, this is materially dangerous because autonomous or mis-prompted agents can act on shared data at scale, so the missing warning increases the chance of unsafe deployment and misuse.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The documentation instructs users to place email and password credentials directly into configuration and shell environment examples without any warning about secret handling. That encourages insecure storage in plaintext config files, shell history, screenshots, or logs, which could expose credentials for the Relay control plane and all accessible shared vault data.

Lp3

Medium
Category
MCP Least Privilege
Confidence
96% confidence
Finding
The skill exposes shell-based capabilities and authenticated remote read/write/delete operations, but it declares no explicit tool scope such as permissions or allowed-tools. That omission increases the chance an agent can invoke shell broadly or use this skill in contexts where operators did not intend external networked file modification, which weakens containment and auditability.

External Transmission

Medium
Category
Data Exfiltration
Content
All API calls require a Bearer JWT token. Get one via login:

```bash
curl -s -X POST "$RELAY_CP_URL/v1/auth/login" \
  -H "Content-Type: application/json" \
  -d '{"email": "'$RELAY_EMAIL'", "password": "'$RELAY_PASSWORD'"}' \
  | jq -r '.access_token'
Confidence
60% 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
When the token expires (1 hour), refresh it:
```bash
curl -s -X POST "$RELAY_CP_URL/v1/auth/refresh" \
  -H "Content-Type: application/json" \
  -d '{"refresh_token": "'$REFRESH_TOKEN'"}'
```
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The skill documents a delete operation against shared collaborative content without any warning, confirmation step, or recovery guidance. In an agent context, this makes accidental or prompt-induced destructive actions more likely, potentially causing irreversible loss of shared notes or disruption for multiple users.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
This markdown API reference documents file creation, file deletion, and full document replacement operations, including DELETE and PUT endpoints that can alter or remove user data. While the mechanics are described, there is no explicit warning calling out that these actions change shared content and may overwrite or delete data, which is the kind of user-impact warning required for markdown files.

Missing User Warnings

Medium
Confidence
85% confidence
Finding
This shell script reads RELAY_EMAIL and RELAY_PASSWORD from the environment and sends them to a remote authentication endpoint via curl. Although the header comments describe usage, they do not clearly warn the user that credentials will be transmitted to a control-plane service, and there is no runtime confirmation or user-facing notice.

External Transmission

Medium
Category
Data Exfiltration
Content
: "${RELAY_EMAIL:?Set RELAY_EMAIL}"
: "${RELAY_PASSWORD:?Set RELAY_PASSWORD}"

resp=$(curl -sf -X POST "${RELAY_CP_URL}/v1/auth/login" \
  -H "Content-Type: application/json" \
  -d "{\"email\": \"${RELAY_EMAIL}\", \"password\": \"${RELAY_PASSWORD}\"}")
Confidence
70% 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
--arg content "$CONTENT" \
  '{share_id: $sid, path: $path, content: $content}')

curl -sf -X POST "${RELAY_CP_URL}/v1/documents/${FOLDER_SHARE_ID}/files" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d "$PAYLOAD" | jq '.'
Confidence
70% 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
--arg content "$CONTENT" \
  '{share_id: $sid, path: $path, content: $content}')

curl -sf -X POST "${RELAY_CP_URL}/v1/documents/${FOLDER_SHARE_ID}/files" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d "$PAYLOAD" | jq '.'
Confidence
70% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The script implements a DELETE operation against shared vault content, while the stated skill scope describes read, create/update, list, and search capabilities but does not mention deletion. This creates a scope mismatch that can lead users or calling agents to invoke destructive behavior they did not explicitly authorize, increasing the risk of accidental or unauthorized data loss in a collaborative environment.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
This code performs a network call to retrieve document content and transmits sensitive values including a bearer token, document ID, share ID, and key. Although comments describe usage, there is no confirmation prompt or user-facing warning that the script will contact a remote Relay service and access protected document data.

External Transmission

Medium
Category
Data Exfiltration
Content
--arg content "$CONTENT" \
    '{share_id: $sid, content: $content, key: "contents"}')

  RESULT=$(curl -sf -X PUT "${RELAY_CP_URL}/v1/documents/${EXISTING_DOC_ID}/content" \
    -H "Authorization: Bearer $TOKEN" \
    -H "Content-Type: application/json" \
    -d "$PAYLOAD")
Confidence
70% 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
--arg key "$KEY" \
  '{share_id: $sid, content: $content, key: $key}')

curl -sf -X PUT "${RELAY_CP_URL}/v1/documents/${DOC_ID}/content" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d "$PAYLOAD" | jq '.'
Confidence
70% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Static analysis

No suspicious patterns detected.