Back to skill

Security audit

Equipment Maintenance Log

Security checks for vulnerabilities and agentic risk

Overview

This maintenance-log skill should be reviewed because it stores records in the user's home directory even though its documentation says outputs stay in the workspace.

Install only if you are comfortable with equipment records being stored in ~/.openclaw/equipment_log.json. Review or change the storage path and permissions before using it for sensitive lab or facility data, and treat reminders as manual command output rather than automatic notifications.

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

Warning
Location
scripts/main.py:16
Finding
Persistent Data File Uses Inherited Permissions and Follows Symbolic Links<![CDATA[ ## Vulnerability Details **File Location**: `scripts/main.py`, lines 16–29 **Vulnerability Type**: Insecure persistent file handling **Risk Level**: Medium ```python def __init__(self, data_file="~/.openclaw/equipment_log.json"): self.data_file = Path(data_file).expanduser() self.data_file.parent.mkdir(parents=True, exist_ok=True) self.equipment = self._load() def _load(self): if self.data_file.exists(): with open(self.data_file) as f: return json.load(f) return {} def _save(self): with open(self.data_file, 'w') as f: json.dump(self.equipment, f, indent=2) ``` The related documentation in `SKILL.md`, lines 43 and 54, states that output is saved to and restricted to the workspace, while the implementation persistently stores records under the user's home directory at `~/.openclaw/equipment_log.json`. ### Technical Analysis The parent directory and data file are created without explicit restrictive permissions. Their resulting permissions therefore depend on the process umask. In an environment with a permissive umask or unsuitable preexisting permissions, equipment names and locations may become accessible to other local accounts. The calls to `open()` also follow symbolic links. The implementation does not verify whether `~/.openclaw`, `equipment_log.json`, or any relevant path component is a symbolic link, nor does it validate ownership and file type before reading or truncating the destination. Opening the file with mode `w` truncates the resolved target before writing JSON. The default path is fixed rather than supplied through the command-line interface, which limits remote exploitability. Exploitation requires local access sufficient to prepare or modify the destination path. In addition, initialization loads an existing destination as JSON before `_save()` is reached, so a symlink overwrite attack requires the linked target to initially contain valid JSON compatible with the expected o ...[truncated 1563 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Store data in a documented, application-controlled location. If workspace-only storage is intended, resolve the destination beneath the workspace and reject paths escaping that boundary. 2. Create the application directory with mode `0700` and verify that it is a real directory owned by the current user. 3. Create data files with mode `0600` rather than relying on the process umask. 4. Reject symbolic links and non-regular files. On supported platforms, use `os.open()` with `O_NOFOLLOW`, `O_CREAT`, and suitable exclusive or ownership checks. 5. Save atomically by writing to a securely created temporary file in the same trusted directory, flushing and synchronizing it, setting mode `0600`, and replacing the destination with `os.replace()`. 6. Before reading or replacing an existing file, use `lstat()` or descriptor-based checks to confirm its type, owner, and expected permissions. Prefer descriptor-relative operations to reduce time-of-check/time-of-use races. 7. Update `SKILL.md` to disclose the actual persistent storage location and the nature of the stored data, or change the implementation so that its behavior matches the workspace-restriction claim. ]]>
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 (3)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The documented purpose claims maintenance reminders, but the described behavior only prints alerts on manual execution and also uses undeclared local storage at ~/.openclaw/equipment_log.json. This mismatch can mislead users about both automation and data handling, causing them to trust the skill with operational workflows or local data changes it does not clearly disclose.

Lp3

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding
The skill indicates file-writing capability through its documented behavior, but it does not declare any explicit tool scope such as permissions or allowed-tools. This creates a transparency and control gap: users and enforcing systems cannot reliably constrain where or how data is written, increasing the risk of unintended local file modification.

Missing User Warnings

Low
Confidence
88% confidence
Finding
The documentation states that output files are written but does not tell users what files will be created or that local data will be modified. This reduces informed consent and can lead to accidental overwrites, unnoticed persistence, or confusion about where potentially sensitive operational data is stored.

Static analysis

No suspicious patterns detected.