Back to skill

Security audit

Jj Mailbox

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly a disclosed file-based messaging tool, but its bundled script can be steered to read, write, or move files outside the declared mailbox folder through unvalidated agent names.

Review before installing. Use only with trusted mailbox repos and trusted agent names, avoid running it on sensitive directories, and prefer a fixed version that validates agent identifiers and rejects traversal, absolute paths, and symlink escapes before reading or writing files.

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

T05 · Unauthorized Access and Privilege Escalation

Error
Location
jj-mailbox.sh:139
Finding
Path Traversal Allows File Access Outside the Mailbox Repository<![CDATA[ ## Vulnerability Details **File Location**: `jj-mailbox.sh:139-155`, `jj-mailbox.sh:167-218`, and `jj-mailbox.sh:232-280` **Vulnerability Type**: Path traversal and insufficient path authorization **Risk Level**: High The script uses agent-controlled identifiers directly as filesystem path components. It does not reject absolute paths, `/`, `..`, or symlinked directories, contradicting the scope guarantee in `SKILL.md:18` that the Skill only accesses files inside `$JJ_MAILBOX_REPO`. ### Vulnerable Code Registration creates directories and files using an unvalidated agent name: ```bash cmd_register() { ensure_repo ensure_jj local name="${1:?Usage: jj-mailbox register <name>}" local desc="${2:-Agent ${name}}" local repo repo="$(get_repo)" cd "${repo}" # Create agent directories mkdir -p "agents/${name}" "inbox/${name}/new" "inbox/${name}/processed" # Write profile cat > "agents/${name}/profile.json" <<EOF { "name": "${name}", "description": "${desc}", "capabilities": [], "platform": "openclaw", "created": "$(ts_iso)" } EOF ``` Message sending uses an unvalidated recipient and sender in directory and filename construction: ```bash cmd_send() { ensure_repo ensure_jj local to="${1:?Usage: jj-mailbox send <to> <subject> <body> [--refs <id1,id2,...>]}" local subject="${2:?}" local body="${3:?}" local refs_arg="" local from from="$(get_agent)" local repo repo="$(get_repo)" # Parse optional --refs flag (remaining args after positional 3) shift 3 || true while [[ $# -gt 0 ]]; do case "$1" in --refs) refs_arg="${2:-}"; shift 2 ;; *) shift ;; esac done cd "${repo}" # Verify recipient exists if [[ ! -d "inbox/${to}/new" ]]; then err "Unknown agent: ${to}" err "Registered agents:" ls agents/ 2>/dev/null || echo " (none)" exit 1 fi local msg_id="msg-$(gen_id)" local ts ts="$(ts_filename)" local filename="${ts}_${from}_${msg_id}.json" # Buil ...[truncated 4744 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. **Strictly validate every agent identifier** Apply the same validation to registration names, recipients, explicit inbox/read selectors, and `JJ_MAILBOX_AGENT`. Use a conservative allowlist, for example: ```bash validate_agent_name() { local name="$1" if [[ ! "$name" =~ ^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$ ]] || [[ "$name" == "." || "$name" == ".." ]]; then err "Invalid agent name" exit 1 fi } ``` This rejects separators, traversal components, whitespace, control characters, and absolute paths. 2. **Canonicalize and enforce repository containment** Resolve the repository and every target path to canonical absolute paths before access. Verify that the result begins with the canonical repository path followed by `/`; a textual prefix check without the separator is insufficient. Prefer descriptor-based or component-by-component traversal protections where available, because simple canonicalization can remain vulnerable to time-of-check/time-of-use races. 3. **Reject symlinked mailbox directories** Before reading or writing, verify that relevant components such as `agents`, `inbox`, the selected agent directory, `new`, and `processed` are real directories and not symbolic links. Do not follow attacker-controlled symlinks outside the repository. 4. **Use safe file creation** Create new messages with exclusive semantics so existing files cannot be overwritten. Ensure the destination directory has already passed containment and symlink checks. 5. **Apply authorization rules** The inbox command should normally only read the current agent's inbox unless an explicit administrative mode is enabled. Avoid accepting arbitrary agent selectors when that capability is not required. 6. **Add regression tests** Test and reject identifiers including: ```text . .. ../target ../../target /tmp/target agent/name agent\name ``` Tests s ...[truncated 165 chars]
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep

Static analysis

No suspicious patterns detected.