Back to skill

Security audit

Taildrop

Security checks for vulnerabilities and agentic risk

Overview

This Taildrop retrieval skill is mostly coherent, but its bundled script has a real command-injection risk in a user-controlled download path.

Review before installing. Use only with trusted, literal destination paths, avoid --overwrite unless you intend to replace files, and prefer fixing the script to remove eval before use. The skill does not show hidden exfiltration or persistence, but the current shell implementation can run unintended local commands if given a malicious path.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/taildrop-get.sh:50
Finding

Command Injection Through User-Controlled Destination Path

Content
View full analysis

Vulnerability Details

File Location: scripts/taildrop-get.sh, lines 50–63
Vulnerability Type: Shell command injection through unsafe use of eval
Risk Level: High

Vulnerable Code

bash
# Build command
CMD="tailscale file get --conflict=$CONFLICT_MODE"
if [ "$LOOP_MODE" = true ]; then
    CMD="$CMD --loop"
fi
CMD="$CMD \"$TARGET_DIR\""

echo "Downloading Taildrop files to: $TARGET_DIR"
echo "Conflict mode: $CONFLICT_MODE"
if [ "$LOOP_MODE" = true ]; then
    echo "Running in loop mode (Ctrl+C to stop)..."
fi

# Execute
eval $CMD

TARGET_DIR originates from an arbitrary positional command-line argument:

bash
*)
    TARGET_DIR="$1"
    shift
    ;;

Technical Analysis

The script constructs a shell command as a string and executes it with eval. Although the destination path is surrounded by embedded quotation marks, eval performs an additional shell-parsing pass. Shell command substitutions within TARGET_DIR, such as $(...), are therefore evaluated as commands rather than treated exclusively as literal path content.

The earlier use of mkdir -p "$TARGET_DIR" does not neutralize this payload. That command correctly treats the value as a literal path, but the same value is subsequently placed into the command string and reparsed by eval.

For example, a destination argument containing $(touch pwned) is initially accepted as a literal directory name. During the eval operation, the command substitution executes touch pwned.

Attack Path

  1. An attacker convinces a user or automation agent to invoke the Skill with a crafted destination argument:

    bash
    ./scripts/taildrop-get.sh '$(touch pwned)'
    
  2. The argument is assigned directly to TARGET_DIR.

  3. mkdir -p "$TARGET_DIR" creates a directory with the literal crafted name.

  4. The script incorporates the untrusted value into the CMD string.

  5. eval $CMD ...[truncated 1033 chars]

Remediation
View remediation

Remediation Suggestions

Remove eval and represent the command as a Bash array. Array expansion preserves argument boundaries and prevents the destination path from being reparsed as shell syntax:

bash
CMD=(tailscale file get "--conflict=$CONFLICT_MODE")

if [[ "$LOOP_MODE" == true ]]; then
    CMD+=(--loop)
fi

CMD+=("$TARGET_DIR")

"${CMD[@]}"

Additional hardening measures should include:

  1. Retain the existing fixed allowlist for conflict modes rather than accepting arbitrary option values.

  2. Use -- before the destination argument if the Tailscale CLI supports it, preventing paths beginning with a hyphen from being interpreted as options:

    bash
    CMD+=(-- "$TARGET_DIR")
    
  3. Avoid all string-based shell command assembly when any component can originate from user input.

  4. Add regression tests using destination names containing command substitutions, spaces, quotation marks, semicolons, and leading hyphens, verifying that they are passed as literal arguments and never executed.

  5. Run the Skill with the least privileges necessary and avoid invoking the entire script through sudo.

Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Rogue AgentSelf-Modification, Session Persistence
  • 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 (8)

Self-Modification

High
Category
Rogue Agent
Confidence
85% confidence
Finding

Skill modifies its own code, configuration, or behavior at runtime. Self-modification enables an agent to escalate privileges, disable safety constraints, or install persistent backdoors.

Content

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

md
# Download to a custom directory
~/clawd/skills/taildrop/scripts/taildrop-get.sh /path/to/directory

# Overwrite existing files
~/clawd/skills/taildrop/scripts/taildrop-get.sh --overwrite

# Rename duplicates

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

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

md
## Prerequisites

- Tailscale must be installed and running
- User must be set as Tailscale operator (run once): `sudo tailscale set --operator=$USER`
- Otherwise, sudo is required for each download

## Notes

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

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

md
## Prerequisites

- Tailscale must be installed and running
- User must be set as Tailscale operator (run once): `sudo tailscale set --operator=$USER`
- Otherwise, sudo is required for each download

## Notes

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · scripts/taildrop-get.sh (reported line 47)May include surrounding context.

sh
## Prerequisites

- Tailscale must be installed and running
- User must be set as Tailscale operator (run once): `sudo tailscale set --operator=$USER`
- Otherwise, sudo is required for each download

## Notes

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · scripts/taildrop-get.sh (reported line 50)May include surrounding context.

sh
## Prerequisites

- Tailscale must be installed and running
- User must be set as Tailscale operator (run once): `sudo tailscale set --operator=$USER`
- Otherwise, sudo is required for each download

## Notes

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
50% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · scripts/taildrop-get.sh (reported line 47)May include surrounding context.

sh
exit 1
fi

# Check if we need sudo
if ! tailscale file get --help &> /dev/null 2>&1; then
    echo "Error: Cannot access Tailscale file commands"
    echo "Run once: sudo tailscale set --operator=\$USER"

Vague Triggers

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

The manifest says to use the skill when the user 'mentions Taildrop,' which is broader than a clear retrieval-specific invocation. A user could reference Taildrop conversationally without wanting to download files, increasing the chance of unintended activation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

This shell script performs file downloads into a user directory and can overwrite existing files when --overwrite is selected, but it provides no confirmation prompt or explicit warning about the data-modifying effect. The existing echo lines describe the destination and mode, but they do not clearly warn the user about possible replacement of local files.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.