Back to skill

Security audit

Grago

Security checks for vulnerabilities and agentic risk

Overview

Grago is transparent about being a local research helper, but it gives an agent broad shell, file, network, and installer authority that needs careful review before use.

Install only on a dedicated, trusted single-user machine where you are comfortable letting the OpenClaw agent run shell commands with your user permissions. Do not use it on shared, public-facing, or sensitive systems. Review commands and sources.yaml files carefully, keep api_base pointed at localhost unless you intend to send data elsewhere, and prefer installing Ollama through a trusted package manager instead of running the bundled curl-to-shell installer path.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (4)

T09 · Insecure Skill Coding Practices

Error
Location
grago.sh:101
Finding

Agent-Controlled Arbitrary Shell Command Execution

Content
View full analysis
/dev/null) || data="[transform failed]" fi ``` ```bash local data data=$(eval "$fetch_cmd") || err "Fetch command failed" if [[ -n "$transform_cmd" ]]; then data=$(echo "$data" | eval "$transform_cmd") || err "Transform failed" fi ``` ### Technical Analysis The `fetch`, `research`, and `pipe` commands pass command-line arguments or YAML-derived transformation values directly to the shell through `eval`. No command allowlist, argument separation, metacharacter validation, sandbox, user confirmation, or privilege reduction is applied. Because `eval` reparses its argument as shell syntax, an attacker can use command substitution, redirection, pipelines, separators, or subshells to execute commands unrelated to data fetching. The AI-facing documentation explicitly encourages an OpenClaw agent to populate these parameters, meaning prompt injection affecting the agent can reach the execution sink. The security documentation acknowledges this behavior, but disclosure does not constrain or mitigate the execution capability. General-purpose shell access is substantially broader than the minimum privilege required to fetch URLs and perform fixed data transformations. ### Attack Path 1. An attacker places malicious instructions in content processed by the OpenClaw agent or otherwise influences a research request. 2. The compromised agent constructs a Grago invocation containing attacker-controlled shell syntax, for example in `--fetch` or `--transform`. 3. `cmd_pipe`, `cmd_fetch`, or `cmd_research` assigns that value to a ...[truncated 969 chars]
Remediation
View remediation

T03 · Remote Payload Retrieval and Execution

Error
Location
install.sh:29
Finding

Unverified Remote Installer Download and Execution

Content
View full analysis
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
grago.sh:137
Finding

Unrestricted Local File Read with Model Endpoint Disclosure

Content
View full analysis
/dev/null) || { log "WARN: Failed $name"; continue; } ;; file) local path path=$(yq -r ".sources[$i].path" "$sources_file") data=$(cat $path 2>/dev/null) || { log "WARN: Failed $name"; continue; } ;; esac ``` ```bash local result result=$(echo "$combined" | analyze "${prompt:-Analyze the following data sources and provide key insights.}") ``` The analysis function can use a configurable endpoint: ```bash local api_base api_base=$(get_config "api_base" "http://localhost:11434/v1") curl -s "${api_base}/chat/completions" \ -H "Content-Type: application/json" \ -d "$payload" | jq -r '.choices[0].message.content // "Error: no response"' ``` ### Technical Analysis A YAML sources file can specify `type: file` and select any path readable by the Grago process. There is no approved-directory policy, canonical-path validation, symlink restriction, sensitive-file denylist, or user confirmation. The path is also expanded without quotes in `cat $path`. This permits shell field splitting and pathname expansion, allowing one YAML value to match or reference multiple files. Although this line does not itself invoke `eval`, its expansion behavior broadens the set of files that can be read. The resulting content is appended to `combined` and automatically supplied to the analysis function. Ollama is attempted first, but if unavailable, the fallback sends the data to the configurable `api_base`. That setting is not restricted to loopback, so local file content can be disclosed to a remote model endpoint. ### Attack Path 1. An attacker supplies a malicious sources file or influences an agent to generate one. 2. The file contains a source with `typ ...[truncated 992 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
grago.sh:98
Finding

Unrestricted URL Fetching Enables Server-Side Request Forgery

Content
View full analysis
/dev/null) || { log "WARN: Failed $name"; continue; } ;; ``` ### Technical Analysis The `fetch` and `research` paths accept arbitrary URLs and pass them to `curl` without validating the scheme, hostname, port, or resolved address. The `-L` option follows redirects, but redirect destinations are not revalidated. Consequently, an attacker who controls an agent request or YAML source can cause requests from the trusted Grago host to loopback services, private network systems, link-local addresses, or cloud metadata endpoints. The host may have access to services that are not reachable by the attacker directly. Responses are returned to the caller or supplied to the model for analysis, creating a channel through which internal response data may be exposed. ### Attack Path 1. An attacker influences a Grago fetch request or a `sources.yaml` URL. 2. The attacker supplies an internal destination directly or an external URL that redirects to one. 3. Grago invokes `curl -sL` from the trusted host. 4. `curl` connects to the internal or link-local target and follows redirects without destination restrictions. 5. The response is printed or included in model analysis. 6. The attacker uses the result to enumerate internal services, retrieve local API data, or access cloud instance metadata. ### Impact Assessment The vulnerability can provide network access from the Grago host to otherwise inaccessible resources. Depending on the deployment environment, the scope may include: - Loopback-only administration or model APIs. - Services on private corporate or home netw ...[truncated 340 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
Findings (22)

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The fetch command executes user-supplied shell via eval in --transform, enabling arbitrary command execution in the context of the user running the script. Because this capability is exposed as part of routine data processing, it can be abused for code execution, data theft, or destructive local actions if arguments or source definitions are untrusted.

Content

No source excerpt is available for this finding.

External Script Fetching

High
Category
Supply Chain
Confidence
99% confidence
Finding

curl -fsSL https://ollama.ai/install.sh | sh downloads executable code from an external source and runs it immediately. In installer context this is especially dangerous because users expect setup scripts to make privileged system changes, so a compromised upstream script can install malware, alter configuration, or exfiltrate secrets with little visibility.

Content

Scanner excerpt · install.sh (reported line 29)May include surrounding context.

sh
exit 1
    fi
  else
    curl -fsSL https://ollama.ai/install.sh | sh
  fi
  echo -e "${GREEN}✓ Ollama installed${NC}"
else

Chaining Abuse

High
Category
Tool Misuse
Confidence
99% confidence
Finding

The | sh construct is a classic unsafe chaining pattern because it turns network data directly into executed commands. It removes opportunities for validation, auditing, and user review, so any compromise of the fetched content immediately becomes code execution on the host.

Content

Scanner excerpt · install.sh (reported line 29)May include surrounding context.

sh
exit 1
    fi
  else
    curl -fsSL https://ollama.ai/install.sh | sh
  fi
  echo -e "${GREEN}✓ Ollama installed${NC}"
else

Unrestricted Tool Access

Medium
Category
Excessive Agency
Confidence
98% confidence
Finding

The skill explicitly grants an agent the ability to execute shell commands and acknowledges that a compromised or prompt-injected agent could run arbitrary commands on the host. In agentic systems, unrestricted shell access is highly dangerous because it can lead to code execution, file theft, persistence, lateral movement, or destructive actions on the local machine.

Content

Scanner excerpt · README.md (reported line 13)May include surrounding context.

md
**Grago executes shell commands by design.** This is intentional and necessary — local LLMs can't use tools natively, so Grago bridges the gap by running commands on your behalf.

**Risk:** If your OpenClaw agent is compromised or prompt-injected, Grago can execute arbitrary commands on your machine.

**Safe for:**
- ✅ Personal Mac Mini / VPS running your own OpenClaw agent

Session Persistence

Medium
Category
Rogue Agent
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.

Content

Scanner excerpt · README.md (reported line 81)May include surrounding context.

md
1. Check for Ollama — install it if missing
2. Pull a recommended local model (Gemma 2 9B by default)
3. Copy `SKILL.md` to your OpenClaw workspace skills folder
4. Create `~/.grago/config.yaml` with sensible defaults

---

Unrestricted Tool Access

Medium
Category
Excessive Agency
Confidence
99% confidence
Finding

The document explicitly states that the skill can execute arbitrary shell commands on the host if the upstream agent is prompt-injected or compromised. Even though this behavior is intentional and framed as part of the product design, unrestricted command execution materially expands the attack surface and can lead to full host compromise, data loss, credential theft, or persistence.

Content

Scanner excerpt · SECURITY.md (reported line 19)May include surrounding context.

md
### The Trade-Off

**Risk:** If your OpenClaw agent is prompt-injected or compromised, Grago can execute arbitrary commands on your machine.

**Mitigation:**
- Grago is designed for **trusted, single-user environments** (your own Mac Mini, VPS, or workstation)

Unrestricted Tool Access

Medium
Category
Excessive Agency
Confidence
98% confidence
Finding

The skill explicitly enables shell-command execution and acknowledges that a compromised or prompt-injected agent could execute arbitrary commands. In the context of an agent skill, this creates a real remote-code-execution pathway with access to local files, network resources, and any privileges of the running user, making the surrounding context more dangerous rather than less.

Content

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

md
**Safe for:** Trusted, single-user environments (your own Mac Mini, VPS, workstation)  
**NOT safe for:** Multi-tenant systems, public APIs, untrusted agents

If your OpenClaw agent is compromised via prompt injection, Grago can execute arbitrary commands. This is the trade-off for free local compute. Read `SECURITY.md` in the repo for full details.

## When to Use This Skill

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · README.md (reported line 107)May include surrounding context.

Pipe any shell command into your local model

grago pipe
--fetch "curl -s https://api.example.com/data"
--transform "jq .results"
--analyze "Identify trends and flag outliers"

text

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · README.md (reported line 158)May include surrounding context.

Pipe any shell command into your local model

grago pipe
--fetch "curl -s https://api.example.com/data"
--transform "jq .results"
--analyze "Identify trends and flag outliers"

text

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

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

Pipe any shell command into your local model

grago pipe
--fetch "curl -s https://api.example.com/data"
--transform "jq .results"
--analyze "Identify trends and flag outliers"

text

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script claims to support 'tool-less local models', but it both fetches remote content and can transmit input to a configurable OpenAI-compatible HTTP endpoint. This mismatch is security-relevant because users may assume all processing is local and may unknowingly expose sensitive fetched or local data to external services.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
94% confidence
Finding

The script transmits prompts and collected data to an external HTTP endpoint using curl, which can expose sensitive or proprietary information outside the local environment. In context, this is more dangerous because the tool also aggregates data from remote sources and local files, making unintended exfiltration of mixed datasets plausible.

Content

Scanner excerpt · grago.sh (reported line 72)May include surrounding context.

sh
--arg user "${prompt}\n\n---\nDATA:\n${input}" \
    '{model: $model, messages: [{role: "system", content: $system}, {role: "user", content: $user}], stream: false}')
  
  curl -s "${api_base}/chat/completions" \
    -H "Content-Type: application/json" \
    -d "$payload" | jq -r '.choices[0].message.content // "Error: no response"'
}

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

Fetched data and potentially local file contents are sent to an HTTP API endpoint without explicit privacy disclosure, so sensitive information may be transmitted off-host unexpectedly. The risk is amplified by the configurable endpoint, which could point to a non-local or untrusted service despite the script's local-model framing.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

Executing shell commands through --transform without clear disclosure is dangerous because users may treat it as a harmless formatting option when it is actually arbitrary code execution. This increases the chance that untrusted examples, copied commands, or generated configs will run unexpected commands on the host.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The research command permits reading arbitrary local files from paths specified in the sources YAML, which exceeds a simple web research role and can expose sensitive local data. Since the collected data is later aggregated and may be sent to a model endpoint, this broad file access materially increases exfiltration risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

Source-level transforms in the research workflow are executed via eval with no clear warning, so a seemingly simple research configuration file can trigger arbitrary shell execution. This is particularly risky because YAML source files are likely to be shared or reused, making malicious transforms easy to hide.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The pipe command executes arbitrary shell through --fetch, which is effectively a generic command runner disguised as a data pipeline feature. Without strong disclosure, users may invoke or paste untrusted commands that can fully compromise the local environment under the user's privileges.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The pipe transform step executes arbitrary shell commands without adequate warning, creating another command-execution path that may be mistaken for benign text processing. This broadens attack surface and makes social engineering via copied command lines more effective.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The installer fetches a shell script from the network and immediately executes it with sh without showing the user the contents, verifying integrity, or requiring explicit confirmation. This creates a direct remote code execution path: if the remote server, DNS, TLS trust chain, or delivery path is compromised, arbitrary commands will run on the user's machine during installation.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
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.

Content

Scanner excerpt · install.sh (reported line 60)May include surrounding context.

sh
INSTALL_DIR="/usr/local/bin"
if [[ ! -w "$INSTALL_DIR" ]]; then
  INSTALL_DIR="$HOME/.local/bin"
  mkdir -p "$INSTALL_DIR"
fi

cp grago.sh "$INSTALL_DIR/grago"

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

Reading arbitrary local files from source definitions without explicit warning is a transparency and safety issue because users may not realize a research config can access host files. While file reading may be intentional in some workflows, the lack of disclosure increases the chance of accidental exposure of sensitive content.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
77% confidence
Finding

The research command writes analysis results to a user-specified file path, which is a file write operation. Although the help mentions '--output Save output to file', there is no additional runtime disclosure before overwriting the target path, so the operation has only minimal warning coverage.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.