T03 · Remote Payload Retrieval and Execution
- Location
references/patchmon-setup.md:114- Finding
Unpinned Remote Installation Script Executed as Root and Installed Persistently
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill is a real server-patching tool, but it asks for broad production access and contains unsafe update, credential, and remote-command handling that should be reviewed before installation.
Install only after reviewing the scripts and tightening controls: remove curl -k, avoid sourcing generated or user-supplied config files, validate hostnames/users/paths, avoid curl | sudo bash for PatchMon, keep Docker updates opt-in, and grant sudo through narrow audited wrappers rather than broad passwordless Docker commands.
references/patchmon-setup.md:114Unpinned Remote Installation Script Executed as Root and Installed Persistently
scripts/patchmon-query.sh:46TLS Certificate Verification Disabled for Credentials and Bearer Tokens
scripts/patchmon-query.sh:87PatchMon API Data Is Converted into Executable Shell Configuration
scripts/patch-host-full.sh:94Untrusted Docker Path Is Interpolated into Remote Shell Commands
scripts/patchmon-query.sh:7Credential and Inventory Configuration Files Are Executed with Source
SETUP.md:108Passwordless Root Docker Permissions Break the Claimed Least-Privilege Boundary
The troubleshooting instruction to cat ~/.ssh/authorized_keys exposes the complete list of trusted public keys for the account in terminal output. While public keys are not secret like private keys, disclosing account access configuration can aid reconnaissance and may leak comments, usernames, hostnames, or key management details in shared support sessions.
Solutions:
# 1. Verify key is added to target host
ssh admin@target "cat ~/.ssh/authorized_keys"
# 2. Check SSH key permissions
ls -la ~/.ssh/id_openclaw
The troubleshooting block combines curl -k with manual authentication testing, weakening transport security for a privileged management system. Disabling certificate validation can let an attacker intercept or tamper with requests and capture PatchMon credentials, especially in enterprise environments using proxies or untrusted networks.
Solutions:
# 1. Test PatchMon connectivity
curl -k https://patchmon.example.com/api/health
# 2. Verify credentials
cat ~/.patchmon-credentials.conf
The code substantially aligns with the core declared purpose of patching Linux packages and updating Docker containers on a remote server. However, parts of the description overstate what this code chunk actually does. Most notably, there is no PatchMon integration and no automatic host detection; instead, the caller must provide user@hostname manually. The script also handles only one host at a time, so the description's implication of multi-host maintenance orchestration is not represented in this chunk. Additionally, while the script includes OS detection and package-manager abstraction for several distributions, it explicitly warns that only Ubuntu has been tested, making the strong support claim somewhat overstated. Because these are material descriptive mismatches rather than mere implementation details, this should be flagged as a mismatch.
The code’s core behavior is host-only Linux package patching via SSH, which partially matches the declared server patching purpose. However, the declared description explicitly includes Docker container updates and PatchMon-based automatic host detection, neither of which appear in this code chunk. The script also only operates on a single provided host argument rather than managing multiple hosts, and it notes that only Ubuntu has been fully tested despite the broad support claim. Because important declared capabilities are absent from the supplied code, the description does not accurately represent this chunk.
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).
Install missing tools:
# Ubuntu/Debian
sudo apt install curl jq
# RHEL/CentOS/Rocky/Alma
sudo dnf install curl jq
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
- Use `/etc/sudoers.d/` files (easier to manage)
- **SSH keys** should be protected
- Use passphrase-protected keys when possible
- Restrict key permissions: `chmod 600 ~/.ssh/id_rsa`
- **Review updates** before applying in production
- Use dry-run mode first
- Test on staging environment
This section explicitly states that broad chat requests default to Docker-changing behavior, including pulling images and recreating containers. Defaulting to the more destructive path without a narrow trigger or approval materially raises the risk of unintended outages, supply-chain exposure from image pulls, and unauthorized maintenance actions.
The workflow includes potentially disruptive and destructive actions such as package upgrades, 'docker system prune -af', image pulls, and 'docker compose up -d' without an explicit warning about service interruption, image/volume implications, rollback considerations, or approval gates. In a server-maintenance skill, omission of these warnings meaningfully raises the risk of production outages and unintended data or state loss.
The shell pipeline chains network retrieval directly into privileged execution, which is a classic abuse pattern because it converts any compromise of the fetched content into immediate root command execution. Given this skill patches Linux servers across multiple hosts, the context increases danger substantially by enabling rapid fleet-wide compromise.
Install PatchMon agent on each monitored host:
curl -sSL https://raw.githubusercontent.com/PatchMon/PatchMon/main/agent/install.sh | sudo bash
Configure agent (/etc/patchmon/config.yml):
This is a true vulnerability because the script sources a temporary config file generated from PatchMon output, which causes any shell code in that file to execute locally with the privileges of the patching process. In this skill’s context, PatchMon is only supposed to supply host metadata, but source "$TEMP_CONFIG" turns a data channel into a code-execution channel, making compromise of PatchMon, its transport, or its output format highly dangerous.
Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.
echo ""
echo "Step 1/5: Updating system packages..."
ssh "$HOST" "sudo $UPDATE_CMD && sudo $UPGRADE_CMD && sudo $AUTOREMOVE_CMD" || {
echo "ERROR: Failed to update packages on $HOST"
exit 1
}
Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.
echo ""
echo "Step 1/5: Updating system packages..."
ssh "$HOST" "sudo $UPDATE_CMD && sudo $UPGRADE_CMD && sudo $AUTOREMOVE_CMD" || {
echo "ERROR: Failed to update packages on $HOST"
exit 1
}
Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.
echo ""
echo "Step 1/5: Updating system packages..."
ssh "$HOST" "sudo $UPDATE_CMD && sudo $UPGRADE_CMD && sudo $AUTOREMOVE_CMD" || {
echo "ERROR: Failed to update packages on $HOST"
exit 1
}
Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.
echo ""
echo "Step 1/5: Updating system packages..."
ssh "$HOST" "sudo $UPDATE_CMD && sudo $UPGRADE_CMD && sudo $AUTOREMOVE_CMD" || {
echo "ERROR: Failed to update packages on $HOST"
exit 1
}
Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.
}
echo "Step 3/5: Pulling updated Docker images..."
ssh "$HOST" "cd $DOCKER_PATH && sudo docker images --format '{{.Repository}}:{{.Tag}}' | grep -v '<none>' | xargs -r -L1 sudo docker pull" || {
echo "WARNING: Some image pulls failed (continuing anyway)"
}
The script directly executes the user-supplied configuration file with source, which allows arbitrary shell commands in that file to run with the privileges of the patching process. In the context of a multi-host patching tool, operators may reasonably treat config files as data, so this creates a dangerous code-execution boundary that can lead to local compromise, credential theft, tampering with update targets, or malicious commands being run before patching begins.
Using curl -k disables certificate verification for the login request that carries PatchMon credentials. In a server-patching skill, this is especially dangerous because it undermines trust in the update-management backend and enables credential theft or session hijacking through man-in-the-middle attacks.
# Authenticate with PatchMon
echo "Authenticating with PatchMon..."
TOKEN=$(curl -s -k -X POST "$PATCHMON_URL/api/auth/login" \
-H "Content-Type: application/json" \
-d "{\"username\":\"$PATCHMON_USERNAME\",\"password\":\"$PATCHMON_PASSWORD\"}" \
| jq -r '.token // .accessToken // empty')
The host-query request also uses curl -k, so the script accepts unauthenticated TLS endpoints when retrieving the list of hosts needing updates. An attacker who can intercept traffic could tamper with the returned host inventory, causing the surrounding patching workflow to target attacker-chosen systems or generate a malicious configuration file from falsified data.
# Query hosts needing updates
echo "Querying hosts from PatchMon..."
HOSTS_JSON=$(curl -s -k "$PATCHMON_URL/api/v1/dashboard/hosts" \
-H "Authorization: Bearer $TOKEN")
# Parse hosts needing updates
The contribution instructions tell users to run scripts against a remote host and a host-only patching script without clearly warning that these commands may connect to real systems and alter their state. In a server patching skill, that omission is risky because contributors may test against production or otherwise sensitive hosts and trigger unintended maintenance actions.
The development setup section includes commands that probe or act on remote hosts but does not warn contributors that these scripts may affect the target machine. Because this skill is specifically designed for Linux patching and Docker updates, the lack of a safety notice increases the chance of accidental changes to live infrastructure during setup or testing.
The README advertises a very broad chat trigger such as 'Update my servers' and says it 'just works', which creates weak activation boundaries for a high-impact skill. In an agent environment, ordinary conversational text can unintentionally invoke live patching across multiple hosts and container workloads, increasing the chance of accidental execution.
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
# 3. Configure PatchMon credentials
cp scripts/patchmon-credentials.example.conf ~/.patchmon-credentials.conf
nano ~/.patchmon-credentials.conf
chmod 600 ~/.patchmon-credentials.conf
# 4. Test with dry-run
scripts/patch-auto.sh --dry-run
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
# 3. Configure PatchMon credentials
cp scripts/patchmon-credentials.example.conf ~/.patchmon-credentials.conf
nano ~/.patchmon-credentials.conf
chmod 600 ~/.patchmon-credentials.conf
# 4. Test with dry-run
scripts/patch-auto.sh --dry-run
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
# 3. Configure PatchMon credentials
cp scripts/patchmon-credentials.example.conf ~/.patchmon-credentials.conf
nano ~/.patchmon-credentials.conf
chmod 600 ~/.patchmon-credentials.conf
# 4. Test with dry-run
scripts/patch-auto.sh --dry-run
The usage section presents natural-language examples like 'Update my servers' and 'What servers need patching?' without clear activation boundaries or explicit confirmation requirements. Because this skill performs operational changes, ambiguous examples increase the risk that a user, another tool, or prompt-injected content triggers patching unintentionally.
No suspicious patterns detected.