Back to skill

Security audit

Log Collector

Security checks for vulnerabilities and agentic risk

Overview

This is a disclosed log-collection daemon, but it uses recurring SSH access to sensitive system logs with unsafe SSH verification and weak credential scoping.

Review before installing. Only run this in a controlled cluster where you are comfortable with recurring central collection of system logs, and require fixes for SSH host-key verification, dedicated key selection, node allowlisting, log redaction/minimization, and retention controls before production use.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/log_collector.py:100
Finding

SSH Host Authentication Is Disabled During Log Collection

Content
View full analysis

Vulnerability Details

File Location: scripts/log_collector.py:100-104
Vulnerability Type: Improper SSH host verification
Risk Level: High

python
result = subprocess.run(
    ['ssh', '-o', 'ConnectTimeout=10', '-o', 'StrictHostKeyChecking=no',
     f'openclaw@{vpn_ip}', cmd],
    capture_output=True, text=True, timeout=30
)

Technical Analysis

The collector explicitly invokes SSH with StrictHostKeyChecking=no. This permits previously unknown SSH host keys to be accepted without confirmation, preventing the collector from reliably establishing that it has connected to the intended node.

The connection is used to retrieve system journals, syslog data, and OpenClaw logs. Consequently, the integrity of all remotely collected records depends on unauthenticated network routing rather than a pinned SSH host identity. The VPN connectivity check performed before SSH does not authenticate the SSH server and therefore does not mitigate this issue.

Attack Path

  1. A configured node has no trusted, pinned entry in the collector account's known_hosts file.
  2. An attacker obtains a network position that permits interception, routing manipulation, VPN-node impersonation, or control of the configured destination address.
  3. The attacker presents an arbitrary SSH host key.
  4. The collector accepts that key because StrictHostKeyChecking=no is enabled.
  5. The collector authenticates and submits its fixed log-collection commands to the impersonated server.
  6. The attacker returns fabricated command output.
  7. The collector stores that output in logs.db as if it came from the legitimate node.

Impact Assessment

An attacker capable of network or destination impersonation can compromise the authenticity and integrity of collected logs. Fabricated records could conceal incidents, create false alerts, or mislead later monitoring and forensic analysis.

The attacker can also observe the command ...[truncated 447 chars]

Remediation
View remediation

Remediation Suggestions

  • Remove StrictHostKeyChecking=no.
  • Use StrictHostKeyChecking=yes for unattended collection.
  • Provision and pin every node's SSH host key before enabling scheduled collection.
  • Use a dedicated, protected known-hosts file, for example:
    python
    [
        'ssh',
        '-o', 'ConnectTimeout=10',
        '-o', 'StrictHostKeyChecking=yes',
        '-o', 'UserKnownHostsFile=/home/openclaw/.ssh/log_collector_known_hosts',
        # Remaining arguments...
    ]
    
  • Populate the dedicated file through an authenticated administrative process rather than dynamically trusting keys returned over the same network being verified.
  • Alert on host-key mismatches instead of automatically replacing or accepting keys.
  • Restrict permissions on the known-hosts file and its parent directory so that the collector account is the only non-administrative account able to access them.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/log_collector.py:100
Finding

Collector Ignores Dedicated Node Keys and Uses Ambient SSH Identities

Content
View full analysis

Vulnerability Details

File Location: scripts/log_collector.py:100-102; related declared configuration at SKILL.md:99-104 and troubleshooting command at SKILL.md:152
Vulnerability Type: Failure to enforce least-privilege SSH identity selection
Risk Level: Medium

The Skill documents dedicated per-node keys:

json
"nodes": [
  {"id": "node1", "local": true},
  {"id": "node2", "ssh_key": "~/.ssh/node2_key"},
  {"id": "node3", "ssh_key": "~/.ssh/node3_key"},
  {"id": "node4", "ssh_key": "~/.ssh/node4_key", "optional": true}
]

It also demonstrates explicit identity selection:

bash
ssh -i ~/.ssh/node2_key openclaw@10.10.0.2

The implementation does not pass an identity file or restrict identity discovery:

python
result = subprocess.run(
    ['ssh', '-o', 'ConnectTimeout=10', '-o', 'StrictHostKeyChecking=no',
     f'openclaw@{vpn_ip}', cmd],

Technical Analysis

The implementation does not read or enforce the documented per-node SSH key path. Because neither -i nor IdentitiesOnly=yes is supplied, OpenSSH may consult the invoking account's SSH configuration, default private-key files, and SSH agent.

This exceeds the minimum credential scope needed for the declared function. A log collector only requires a dedicated identity authorized to read a narrow set of logs. It should not be able to select unrelated ambient identities that may possess broader access.

The pre-scan reference at SKILL.md:152 does not write to an SSH key file. It reads an existing key as an identity for a troubleshooting command. The security concern is therefore not key-file modification; it is the implementation's failure to enforce the dedicated-key model described by that command and the configuration example.

Attack Path

  1. The collector runs in an environment containing default SSH keys, an SSH agent, or user-level SSH configuration.
  2. A remote node is selected from the local ...[truncated 1363 chars]
Remediation
View remediation

Remediation Suggestions

  • Load the intended SSH key path from the node configuration and validate it before invocation.
  • Resolve the path safely and require it to be located in an approved SSH-key directory.
  • Reject missing files, symbolic-link surprises, group-writable keys, world-writable keys, and keys not owned by the expected collector account.
  • Invoke SSH with explicit identity isolation:
    python
    [
        'ssh',
        '-i', validated_key_path,
        '-o', 'IdentitiesOnly=yes',
        '-o', 'IdentityAgent=none',
        '-o', 'StrictHostKeyChecking=yes',
        f'openclaw@{vpn_ip}',
        cmd,
    ]
    
  • Use a distinct key for each node or trust boundary.
  • Configure each remote authorized_keys entry with restrictions such as a forced read-only collection command, disabled port forwarding, disabled agent forwarding, disabled X11 forwarding, and disabled PTY allocation.
  • Grant the remote openclaw account access only to the specific log sources required by the collector.
  • Ensure private-key files are readable only by the collector account and are not shared with administrative workflows.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • 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
Findings (9)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill describes shell execution, SSH access to multiple nodes, database writes, and scheduled destructive cleanup, but it does not declare an explicit tool scope such as permissions or allowed-tools. That mismatch increases the risk of overbroad execution because an agent may infer it is allowed to run remote commands and modify local state without clear guardrails or operator consent.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill enables broad remote log collection and storage from all nodes over SSH/VPN, which can capture sensitive operational data, credentials, tokens, command history, and personal information. Omitting a prominent warning and consent boundary makes the capability more dangerous because users may invoke it without understanding the monitoring scope or privacy and security implications.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/log_collector.py (reported line 66)May include surrounding context.

python
def check_vpn(self, ip):
        """Prüft ob VPN-IP erreichbar ist"""
        try:
            result = subprocess.run(
                ['ping', '-c', '1', '-W', '3', ip],
                capture_output=True, timeout=10
            )

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This code connects to remote nodes and collects journal and syslog content, which can contain sensitive operational or user-related data. Although the code logs progress messages, it does not provide any disclosure or warning that data from remote systems will be transmitted and stored, and that behavior is not explained in a user-facing warning within this file.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
99% confidence
Finding

The SSH command disables host key verification via StrictHostKeyChecking=no, which makes man-in-the-middle impersonation of remote nodes much easier. Because this agent collects sensitive system logs over SSH from multiple nodes, an attacker on the network or VPN could spoof a host, capture credentials/session data, or feed falsified log output into the central database.

Content

Scanner excerpt · scripts/log_collector.py (reported line 102)May include surrounding context.

python
logs_collected = []
            for cmd in log_commands:
                result = subprocess.run(
                    ['ssh', '-o', 'ConnectTimeout=10', '-o', 'StrictHostKeyChecking=no',
                     f'openclaw@{vpn_ip}', cmd],
                    capture_output=True, text=True, timeout=30

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

Starting at L008, the operational documentation is written in German, and the file does not indicate that this locale is optional or required for a region-specific purpose. This can violate language/locale policy when a skill imposes a specific language without user opt-in.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The documented retention cleanup automatically deletes stored logs after 30 days, which is a destructive action that can affect investigations, audits, or compliance if operators are not warned. In this context the feature is operationally normal, but the lack of disclosure can still cause unintended data loss or mismatch with retention requirements.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file-level natural-language description is written in German and states the skill purpose only in that locale, with no indication that language choice is optional or region-specific. Under the policy, hard-coding a specific language without opt-in can be a locale-policy violation.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

The docstring on L049 says the method reads schema.sql 'falls DB leer' (if the DB is empty), which implies a broader condition than what the implementation enforces. The code actually checks only whether sqlite_master contains any tables, so a non-empty database file without tables would still trigger schema execution; this is a documentation-to-code mismatch.

Content

No source excerpt is available for this finding.