T03 · Remote Payload Retrieval and Execution
- Location
setupSkill.md:66- Finding
Unpinned Remote Repository Is Cloned and Executed Without Verification
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill has a coherent developer purpose, but its setup guide gives an agent broad authority to run unverified code, inspect credentials, and change host/auth state without enough user control.
Do not run this setup unattended. Before installing, require a version pinned to a reviewed commit, explicit approval for sudo/Docker/database/token operations, user-provided or secret-manager credentials instead of cross-project discovery, and removal of plaintext token generation and hard-coded encryption material.
setupSkill.md:66Unpinned Remote Repository Is Cloned and Executed Without Verification
setupSkill.md:16Setup Instructions Suppress User Approval for Security-Sensitive Actions
setupSkill.md:106Credential Discovery Dumps Environment Data from Unrelated Projects and Containers
setupSkill.md:182Unattended Setup Grants Root-Equivalent Docker Access and Modifies the Host
setupSkill.md:298Hard-Coded Encryption Key and Predictable Plaintext Token File Expose Trigger.dev Credentials
The setup explicitly instructs the agent to inspect another local project, search environment files and Docker container configuration, and extract AI_API_KEY/model settings for reuse. That is cross-project secret harvesting without user confirmation, which violates least-privilege boundaries and could expose credentials from an unrelated system.
The instructions tell the agent to retrieve sensitive credentials from a separate local 'openclaw' project and running containers, then reuse them in this project, all without asking the user. In the context of an autonomous setup skill, this is especially dangerous because the skill explicitly suppresses user confirmation and encourages independent investigation of sensitive local resources.
Writing AI_BASE_URL values is not secret by itself, but this line is part of a sequence that persists harvested credential material into .env. In context, it contributes to unauthorized secret handling and local storage of sensitive configuration sourced from another project.
Once you have AI_BASE_URL, AI_API_KEY, and MODEL_ID, write them to .env in this project:
sed -i '' "s|^AI_BASE_URL=.*|AI_BASE_URL=<value>|" .env
sed -i '' "s|^AI_API_KEY=.*|AI_API_KEY=<value>|" .env
sed -i '' "s|^MODEL_ID=.*|MODEL_ID=<value>|" .env
This line writes AI_API_KEY into .env, creating a plaintext local copy of a sensitive credential that the instructions previously harvested from another project/container. That combines unauthorized access with insecure persistence, making compromise and later leakage more likely.
sed -i '' "s|^AI_BASE_URL=.*|AI_BASE_URL=<value>|" .env
sed -i '' "s|^AI_API_KEY=.*|AI_API_KEY=<value>|" .env
sed -i '' "s|^MODEL_ID=.*|MODEL_ID=<value>|" .env
Persisting MODEL_ID is less sensitive than an API key, but here it is part of a broader secret-access workflow and may reveal provider/model usage details from another project. In context it helps operationalize unauthorized reuse of another application's AI configuration.
sed -i '' "s|^AI_BASE_URL=.*|AI_BASE_URL=<value>|" .env
sed -i '' "s|^AI_API_KEY=.*|AI_API_KEY=<value>|" .env
sed -i '' "s|^MODEL_ID=.*|MODEL_ID=<value>|" .env
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
If Step 6 failed to find real LLM credentials and .env is missing AI_BASE_URL, AI_API_KEY, or MODEL_ID, fill them with placeholders only for this test so the worker starts:
grep -q "^AI_API_KEY=" .env || echo "AI_API_KEY=placeholder" >> .env
grep -q "^AI_BASE_URL=" .env || echo "AI_BASE_URL=http://placeholder.local/v1" >> .env
grep -q "^MODEL_ID=" .env || echo "MODEL_ID=placeholder-model" >> .env
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
If Step 6 failed to find real LLM credentials and .env is missing AI_BASE_URL, AI_API_KEY, or MODEL_ID, fill them with placeholders only for this test so the worker starts:
grep -q "^AI_API_KEY=" .env || echo "AI_API_KEY=placeholder" >> .env
grep -q "^AI_BASE_URL=" .env || echo "AI_BASE_URL=http://placeholder.local/v1" >> .env
grep -q "^MODEL_ID=" .env || echo "MODEL_ID=placeholder-model" >> .env
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
If Step 6 failed to find real LLM credentials and .env is missing AI_BASE_URL, AI_API_KEY, or MODEL_ID, fill them with placeholders only for this test so the worker starts:
grep -q "^AI_API_KEY=" .env || echo "AI_API_KEY=placeholder" >> .env
grep -q "^AI_BASE_URL=" .env || echo "AI_BASE_URL=http://placeholder.local/v1" >> .env
grep -q "^MODEL_ID=" .env || echo "MODEL_ID=placeholder-model" >> .env
Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.
Linux:
sudo apt-get update && sudo apt-get install -y docker.io docker-compose-plugin
sudo systemctl start docker
sudo usermod -aG docker $USER && newgrp docker
The recovery sections direct extraction of secret keys and PATs from databases and logs, and even manual regeneration/insertion of authentication material. This teaches an agent to access and manipulate live secrets directly, expanding compromise scope and risking credential disclosure, persistence abuse, and account takeover.
These sections instruct extraction of secrets from logs, databases, and local config, followed by writing them into accessible files like .env and CLI config. That behavior effectively operationalizes credential theft and secret redistribution, which can enable lateral movement and durable unauthorized access.
This step reads TRIGGER_ACCESS_TOKEN from .env for reuse in CLI config, directly handling a live authentication token. It increases the secret's exposure surface and supports silent credential propagation to additional files and tools.
If the self-hosted profile is missing or has a placeholder token:
PAT=$(grep TRIGGER_ACCESS_TOKEN .env | cut -d= -f2)
node -e "
const fs = require('fs');
This line writes a generated TRIGGER_ACCESS_TOKEN into .env, persisting a powerful authentication secret in plaintext. Because nearby steps generate and insert the token manually into the database, this creates both an unauthorized auth artifact and an easy-to-leak local copy.
```bash
# Write to .env
sed -i '' "s|^TRIGGER_ACCESS_TOKEN=.*|TRIGGER_ACCESS_TOKEN=$TOKEN|" .env
Although this line is adjacent formatting/context, it belongs to the same instruction block that persists an access token to .env. In context it is part of the vulnerable secret-handling flow and reinforces insecure local storage of auth material.
# Write to .env
sed -i '' "s|^TRIGGER_ACCESS_TOKEN=.*|TRIGGER_ACCESS_TOKEN=$TOKEN|" .env
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.
| Mode | Behavior |
|---|---|
| `"none"` | Auto-approve. Trigger next stage immediately. |
| `"agent"` | Call a reviewer agent. If approved, continue. If rejected, feed feedback back to the previous stage for revision. |
| `"human"` | Set a status in the DB to `pending`. Return. A human reviews externally. Resume the pipeline via an API callback. |
The rule to run every step in sequence with no skipping or asking the user encourages fully autonomous execution of potentially sensitive actions. In this file, that autonomy is coupled with credential harvesting, DB inspection, and token manipulation, which removes an important human approval checkpoint before privileged operations.
These apply for the entire setup without exception.
1. **Run every step in sequence.** No skipping, no asking the user whether to continue.
2. **Never stop for user input.** Every known failure has a recovery path in this file. Go there, fix it, resume.
3. **If a fix is not in this file, find the solution independently.** Read logs, inspect the DB, check config files. Do not ask the user.
4. **Never change package versions or swap libraries to fix an error.** All versions in `package.json` are pinned intentionally. If a version mismatch appears to be the problem, the fix is in the configuration — not in bumping or changing a dependency.
The instruction to 'find the solution independently' by reading logs, inspecting the DB, and checking config files, while explicitly forbidding asking the user, authorizes unsupervised exploration of sensitive assets. In context, this materially increases risk because later sections direct extraction and reuse of secrets from those exact sources.
1. **Run every step in sequence.** No skipping, no asking the user whether to continue.
2. **Never stop for user input.** Every known failure has a recovery path in this file. Go there, fix it, resume.
3. **If a fix is not in this file, find the solution independently.** Read logs, inspect the DB, check config files. Do not ask the user.
4. **Never change package versions or swap libraries to fix an error.** All versions in `package.json` are pinned intentionally. If a version mismatch appears to be the problem, the fix is in the configuration — not in bumping or changing a dependency.
5. **After any recovery, re-run only the step that failed** — not the full `./setup.sh` — unless the recovery section says otherwise.
6. **Confirm expected output before moving to the next step.** Each step specifies what success looks like. Match it before continuing.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
Before doing anything, verify the stack is not already up.
curl -s http://localhost:3000/health
If this returns {"status":"ok",...}, the stack is already running. Skip to the Post-Setup Checklist and confirm all checks pass. If they do, setup is complete — do not re-run anything.
The file instructs the agent to copy discovered LLM credentials into .env with no warning, approval gate, or guidance on secure handling. This normalizes secret collection and local persistence, increasing the chance of accidental exposure through shell history, repo leakage, backups, or logs.
The /pipeline POST sends user-controlled prompt data into a system configured with harvested LLM credentials, likely causing downstream transmission to the external model provider. In isolation this could be normal app behavior, but in this skill's context it follows unauthorized credential collection and automated setup, making the outbound flow riskier because it may activate external services using improperly sourced secrets.
Once real LLM credentials are in .env from Step 6:
curl -X POST http://localhost:3000/pipeline \
-H "Content-Type: application/json" \
-d '{"prompt": "Build a URL shortener service"}'
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
Linux:
sudo apt-get update && sudo apt-get install -y docker.io docker-compose-plugin
sudo systemctl start docker
sudo usermod -aG docker $USER && newgrp docker
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
Linux:
sudo apt-get update && sudo apt-get install -y docker.io docker-compose-plugin
sudo systemctl start docker
sudo usermod -aG docker $USER && newgrp docker
Adding the current user to the docker group effectively grants root-equivalent access on many systems, because Docker can be used to mount the host filesystem and escape normal user restrictions. In an autonomous setup skill, instructing this without clear warning or user approval is dangerous.
sudo apt-get update && sudo apt-get install -y docker.io docker-compose-plugin
sudo systemctl start docker
sudo usermod -aG docker $USER && newgrp docker
Re-run ./setup.sh after Docker is running.
The recovery flow reads tokens from .env, writes them into local CLI credential files, and updates auth configuration without any user-facing warning. This expands the number of secret copies on disk and creates additional persistence points that may be overlooked and later exposed.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
Common values:
- OpenAI: `AI_BASE_URL=https://api.openai.com/v1`
- OpenRouter: `AI_BASE_URL=https://openrouter.ai/api/v1`
- Ollama: `AI_BASE_URL=http://localhost:11434/v1`, `AI_API_KEY=ollama`
No suspicious patterns detected.