Back to skill

Security audit

Agent Bridge Kit

Security checks for vulnerabilities and agentic risk

Overview

The skill is a real social-platform bridge, but it under-discloses credential-file use, Colony posting, and local token/log persistence.

Review the config before use, especially any credential paths and enabled platforms. Use dedicated low-privilege platform credentials, avoid pointing credential settings at arbitrary files, and expect post, crosspost, comment, upvote, and register commands to contact external services and potentially affect public accounts.

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

Warning
Location
scripts/lib/config.sh:38
Finding
Unrestricted Colony credential path can cause arbitrary local file disclosure<![CDATA[ ## Vulnerability Details **File Location**: `scripts/lib/config.sh:38-44`, `scripts/adapters/colony.sh:17-29`, `scripts/adapters/colony.sh:52-54` **Related Configuration**: `bridge.json:19-22` **Vulnerability Type**: Unrestricted credential-file access and external disclosure **Risk Level**: Medium ### Vulnerable Code From `scripts/lib/config.sh:38-44`: ```bash resolve_credentials() { local cred_path cred_path="$(config_get ".platforms.${1}.credentials")" [[ -z "$cred_path" ]] && return 1 cred_path="${cred_path/#\~/$HOME}" [[ -f "$cred_path" ]] || return 1 echo "$cred_path" } ``` From `scripts/adapters/colony.sh:17-29`: ```bash get_api_key() { local cred_file cred_file="$(resolve_credentials colony)" || { # Fall back to env var [[ -n "${COLONY_API_KEY:-}" ]] && { echo "$COLONY_API_KEY"; return 0; } return 1 } # Support both plain text and JSON formats if head -1 "$cred_file" | grep -q '{'; then jq -r '.api_key // .key // .token // empty' "$cred_file" 2>/dev/null else cat "$cred_file" | tr -d '\n' fi } ``` From `scripts/adapters/colony.sh:52-54`: ```bash response=$(curl -s -w "\n%{http_code}" -X POST "$COLONY_API/auth/token" \ -H "Content-Type: application/json" \ -d "$(jq -n --arg key "$api_key" '{api_key: $key}')") ``` The default configuration at `bridge.json:19-22` is: ```json "colony": { "enabled": true, "credentials": "~/.config/colony/credentials.json", "auto_read": true } ``` ### Technical Analysis The Colony credential path is read directly from configuration and is only checked with `-f`. The implementation does not: - Restrict the path to a dedicated credential directory. - Require a specific filename or canonical path. - Reject symbolic links. - Verify file ownership or permissions. - Require a strict JSON credential schema. - Limit the amount of data read. For files not recognized as JSON by the first-line heuristic, the entire file is treated as a plaintext API key. It ...[truncated 1995 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Prefer `COLONY_API_KEY` or an operating-system credential manager instead of configurable arbitrary file paths. 2. If file-based credentials remain supported, restrict them to a dedicated user-private directory such as `~/.config/agent-bridge/credentials/`. 3. Resolve the canonical path and verify that it remains inside the approved directory. 4. Reject symbolic links and non-regular files. 5. Require a strict JSON document containing only the expected `api_key` field; remove the plaintext-file fallback. 6. Validate that the credential file is owned by the current user and is not accessible by group or other users. 7. Apply a reasonable maximum file size before reading it. 8. Treat externally supplied `BRIDGE_CONFIG` files as untrusted and require explicit user confirmation before using credential paths from them. 9. Prefer environment variables before file lookup so ordinary operation does not require filesystem credential access. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/adapters/colony.sh:57
Finding
Colony bearer token cache is written without restrictive permissions<![CDATA[ ## Vulnerability Details **File Location**: `scripts/adapters/colony.sh:12-13`, `scripts/adapters/colony.sh:35-38`, `scripts/adapters/colony.sh:57-60` **Vulnerability Type**: Insecure storage of authentication tokens **Risk Level**: Medium ### Vulnerable Code From `scripts/adapters/colony.sh:12-13`: ```bash COLONY_API="https://thecolony.cc/api/v1" COLONY_TOKEN_CACHE="${BRIDGE_DIR:-$HOME/.config/agent-bridge}/data/.colony-token" ``` From `scripts/adapters/colony.sh:35-38`: ```bash if [[ -f "$COLONY_TOKEN_CACHE" ]]; then local cached_time cached_token cached_time=$(stat -f %m "$COLONY_TOKEN_CACHE" 2>/dev/null || stat -c %Y "$COLONY_TOKEN_CACHE" 2>/dev/null || echo 0) local now ``` From `scripts/adapters/colony.sh:57-60`: ```bash if [[ -n "$token" ]]; then # Cache the token mkdir -p "$(dirname "$COLONY_TOKEN_CACHE")" echo "$token" > "$COLONY_TOKEN_CACHE" echo "$token" ``` ### Technical Analysis The adapter caches a Colony JWT in a plaintext file without setting an explicit restrictive umask, directory mode, or file mode. The resulting permissions therefore depend on the process environment. Under a permissive umask, the token may be readable by other local users or processes. The default cache location can also resolve beneath the Skill project directory because `BRIDGE_DIR` is defined by the sourced utility script. This increases the chance that the cache is included in project backups, copied with the project, or exposed through overly broad project-directory permissions. The code also follows normal filesystem path resolution when reading and writing the cache. It does not check whether the cache path is a symbolic link or verify ownership before trusting an existing cached token. ### Attack Path 1. The user invokes an authenticated Colony command. 2. The adapter exchanges the configured API key for a JWT. 3. The adapter creates the cache directory using ambient permissions and writes the JWT using the caller's current umask ...[truncated 1080 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Store the token under a user-private state directory rather than inside the Skill project, for example `${XDG_STATE_HOME:-$HOME/.local/state}/agent-bridge/`. 2. Set `umask 077` before creating the cache directory or file. 3. Create the cache directory with mode `0700`. 4. Create the token file with mode `0600` and verify the final mode after creation. 5. Write tokens atomically through a securely created temporary file in the same private directory, then rename it. 6. Reject symbolic links and verify that existing cache files are regular files owned by the current user. 7. Remove expired or invalid tokens promptly. 8. Where practical, avoid persistent token caching or use an operating-system credential store. 9. Ensure project packaging and backup rules explicitly exclude token-cache files. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (13)

Credential Access

High
Category
Privilege Escalation
Content
"platforms": {
    "moltbook": {
      "enabled": true,
      "credentials": "~/.config/moltbook/credentials.json",
      "default_submolt": "general",
      "auto_read": true
    },
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
"platforms": {
    "moltbook": {
      "enabled": true,
      "credentials": "~/.config/moltbook/credentials.json",
      "default_submolt": "general",
      "auto_read": true
    },
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The skill documents commands that perform live external write actions such as posting, cross-posting, commenting, upvoting, and account registration, but it does not clearly warn users that these commands will immediately affect third-party platforms. In an agent context, this increases the risk of unintended outbound actions, spam, reputation damage, and accidental use of real credentials or production accounts.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The script reads a Colony API key from credentials or the COLONY_API_KEY environment variable, exchanges it for a JWT over the network, and caches that token to a local file. While there are internal comments and error logs, there is no user-facing warning or explicit disclosure that credentials will be read and an auth token will be stored on disk.

External Transmission

Medium
Category
Data Exfiltration
Content
api_key="$(get_api_key)" || return 1

  local response http_code body_resp
  response=$(curl -s -w "\n%{http_code}" -X POST "$COLONY_API/auth/token" \
    -H "Content-Type: application/json" \
    -d "$(jq -n --arg key "$api_key" '{api_key: $key}')")
  http_code=$(echo "$response" | tail -1)
Confidence
70% 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
87% confidence
Finding
The post command sends user-supplied title, body, tags, and colony identifiers to the Colony API via HTTP POST. Although network posting is part of the adapter's purpose, this file does not provide a user-facing disclosure at the operation point about transmitting content to an external service.

External Transmission

Medium
Category
Data Exfiltration
Content
fi

  local response http_code body_resp
  response=$(curl -s -w "\n%{http_code}" -X POST "$COLONY_API/posts" \
    -H "$(auth_header)" -H "Content-Type: application/json" -d "$payload")
  http_code=$(echo "$response" | tail -1)
  body_resp=$(echo "$response" | sed '$d')
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
fi

  local response http_code body_resp
  response=$(curl -s -w "\n%{http_code}" -X POST "$COLONY_API/posts" \
    -H "$(auth_header)" -H "Content-Type: application/json" -d "$payload")
  http_code=$(echo "$response" | tail -1)
  body_resp=$(echo "$response" | sed '$d')
Confidence
70% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Intent-Code Divergence

Medium
Confidence
95% confidence
Finding
The file-level comments frame the adapter as read-oriented and imply write behavior is not yet present. However, the implemented `cmd_register` function sends a POST request to `/api/register`, which is a write-like external action already available in the code.

External Transmission

Medium
Category
Data Exfiltration
Content
--arg ownerUrl "$owner_url" \
    '{name: $name, platform: $platform, ownerUrl: $ownerUrl}')

  curl -sS -X POST "$API_BASE/api/register" \
    -H "Content-Type: application/json" \
    -d "$payload" | jq '{
      platform: "foragents",
Confidence
88% confidence
Finding
This command performs an outbound POST to a remote endpoint, sending locally sourced metadata from configuration and arguments. While the transmission is over HTTPS and appears functionally legitimate, any external transmission in an agent adapter is security-relevant because it can disclose environment-specific information or be triggered in automation without strong user awareness.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The register command transmits agent metadata, including agent name and homepage URL, to an external service without any interactive warning, confirmation, or prominent disclosure at the point of execution. In an agent-skill context, this increases the risk of unintended outbound sharing of local configuration-derived metadata when a caller invokes registration without understanding the privacy implications.

External Transmission

Medium
Category
Data Exfiltration
Content
'{title: $title, body: $body, submolt: $submolt}')

  local response http_code body_resp
  response=$(curl -s -w "\n%{http_code}" -X POST "$MOLTBOOK_API/posts" \
    -H "$(auth_header)" -H "Content-Type: application/json" -d "$payload")
  http_code=$(echo "$response" | tail -1)
  body_resp=$(echo "$response" | sed '$d')
Confidence
70% 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

Low
Confidence
92% confidence
Finding
The crosspost command persistently records post titles, timestamps, and platform results to data/crosspost-log.json without any explicit user disclosure, opt-in, retention control, or permission hardening. In an agent skill context, persisted activity logs can unintentionally expose sensitive prompts, post metadata, or behavioral history to other local users, backups, or later components that read the workspace.

Static analysis

No suspicious patterns detected.