Back to skill

Security audit

goal-agent

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed goal-agent scaffolder, but it asks users to activate broad autonomous agent behavior and includes a shell templating flaw that can turn crafted inputs into command execution.

Install only if you are comfortable reviewing and constraining an autonomous loop yourself. Run it in a dedicated workspace or VM, avoid untrusted --goal/--metric/--constraints values, inspect any generated files before copying HEARTBEAT.md into ~/clawd/HEARTBEAT.md, and avoid using an output directory containing existing important files.

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/scaffold.sh:97
Finding

Arbitrary Command Execution Through Sed Template Injection

Content
View full analysis

Vulnerability Details

File Location: scripts/scaffold.sh, lines 97-111
Vulnerability Type: GNU sed program injection leading to command execution
Risk Level: High

Vulnerable Code

bash
render_template() {
  local tmpl="$1"
  local out="$2"

  # Use @ as separator to avoid conflicts with / in paths and commands
  sed \
    -e "s@{{GOAL_DESCRIPTION}}@${GOAL}@g" \
    -e "s@{{METRIC_COMMAND}}@${METRIC}@g" \
    -e "s@{{TARGET_VALUE}}@${TARGET}@g" \
    -e "s@{{DIRECTION}}@${DIRECTION}@g" \
    -e "s@{{DIRECTION_VERB}}@${DIRECTION_VERB}@g" \
    -e "s@{{CONSTRAINTS}}@${CONSTRAINTS}@g" \
    -e "s@{{MAX_ITERATIONS}}@${MAX_ITERATIONS}@g" \
    "$tmpl" > "$out"
}

Technical Analysis

The script interpolates command-line values directly into double-quoted sed programs. The --goal, --metric, and --constraints values are not escaped before being placed in the replacement portion of a sed substitution.

Quoting the shell variables prevents ordinary shell word splitting, but it does not make the resulting sed program safe. An attacker can provide delimiters and newline characters that terminate the intended substitution and introduce additional sed commands. GNU sed supports the e command, which executes a shell command. Consequently, a malicious value can transform the generated sed script into one that runs arbitrary operating-system commands.

A conceptual malicious value can have the following structure:

text
replacement@g
e attacker-controlled-command
# trailing text

The injected @g closes the original substitution, the newline introduces a standalone GNU sed e command, and the comment neutralizes the remaining generated text. Backslashes and ampersands can also alter replacement semantics, while an unescaped @ can corrupt generation or terminate the expression.

The issue affects values that are not restricted to safe character sets, particularly:

...[truncated 2048 chars]

Remediation
View remediation

Remediation Suggestions

  1. Do not construct sed source code by interpolating untrusted values. Replace the sed-based renderer with an implementation that passes template values as data rather than executable syntax. A small Python renderer using literal string replacement is appropriate:

    bash
    python3 - "$tmpl" "$out" \
      "$GOAL" "$METRIC" "$TARGET" "$DIRECTION" \
      "$DIRECTION_VERB" "$CONSTRAINTS" "$MAX_ITERATIONS" <<'PY'
    import sys
    
    tmpl, out, goal, metric, target, direction, verb, constraints, maximum = sys.argv[1:]
    replacements = {
        "{{GOAL_DESCRIPTION}}": goal,
        "{{METRIC_COMMAND}}": metric,
        "{{TARGET_VALUE}}": target,
        "{{DIRECTION}}": direction,
        "{{DIRECTION_VERB}}": verb,
        "{{CONSTRAINTS}}": constraints,
        "{{MAX_ITERATIONS}}": maximum,
    }
    
    with open(tmpl, "r", encoding="utf-8") as source:
        content = source.read()
    
    for marker, value in replacements.items():
        content = content.replace(marker, value)
    
    with open(out, "w", encoding="utf-8") as destination:
        destination.write(content)
    PY
    
  2. If sed must be retained, implement and test a dedicated escaping function for the replacement context. It must safely encode the selected delimiter, backslashes, ampersands, and embedded newlines. Merely choosing an uncommon delimiter is insufficient.

  3. Validate all free-form inputs and reject control characters where multiline values are not explicitly required.

  4. Add regression tests using values containing @, &, backslashes, semicolons, command substitutions, and newline-delimited sed commands. Tests should verify both literal output and absence of side effects.

  5. Restore or package the referenced template files and fail explicitly if the template directory is unavailable. This addresses the separate functionality defect and allows the renderer to be tested under its intended execution cond ...[truncated 181 chars]

Vulnerability Patterns
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (5)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The code is a workspace scaffolder, not an operating self-learning agent. It accepts goal/metric/target parameters, validates them, and writes templated markdown and shell files to an output directory. Although the generated files may be intended to support a future agent workflow, this code chunk itself does not execute heartbeat cycles, run the metric command, update strategy based on results, or continue until the goal is met. Therefore the declared description materially overstates the implemented behavior.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill explicitly instructs users to run shell commands and to replace the agent's HEARTBEAT.md with generated autonomous-loop instructions, yet it declares no tool scope or permission boundaries. In practice, this means a powerful shell-capable workflow can be activated without any machine-readable restriction on filesystem, network, or command execution, increasing the chance of unsafe autonomous actions.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

The script unconditionally writes multiple files into the chosen output directory using shell redirection, which will overwrite existing files with the same names without prompting or warning. In the context of an agent scaffolder, this can destroy prior goal, strategy, learning, or evaluation artifacts and may cause accidental loss of work or replacement of trusted scripts.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.