T09 · Insecure Skill Coding Practices
- Location
scripts/validate_setup.py:56- Finding
Untrusted Plugin Name Embedded in an Unquoted Remediation Command
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill appears intended as a setup security checker, but its validation is overstated and it can present unsafe or destructive remediation commands without enough guardrails.
Review this before installing. It is not clearly malicious, but treat it as a basic diagnostic helper rather than a complete security validator. Do not blindly run generated fix commands, especially plugin removal, config reset, global update, or commands containing plugin names from your filesystem. Only enable the cron job if you want recurring local checks and understand what paths and commands it will use.
scripts/validate_setup.py:56Untrusted Plugin Name Embedded in an Unquoted Remediation Command
scripts/validate_setup.py:55Plugin Safety Check Accepts Malicious Plugins with Minimal Manifests
scripts/validate_setup.py:107Sandbox Validation Accepts Disabled or Unrelated Configuration
scripts/validate_setup.py:35Permission Check Fails to Detect World-Readable Configuration
The skill instructs users to run Python scripts and cron jobs that clearly require shell execution and filesystem access, but it does not declare any tool scope such as permissions or allowed-tools. That mismatch weakens policy enforcement and reviewability, increasing the chance the skill executes with broader capabilities than intended.
The activation guidance says to use the skill during initial setup, periodic heartbeats, or whenever security validation is required, which is broad enough to trigger frequent or automatic execution. For a skill that invokes local scripts and shell commands, ambiguous activation expands the attack surface and may cause it to run in contexts where its behavior has not been sufficiently reviewed.
Skill grants unrestricted tool access without appropriate constraints. An agent with unfettered tool access can perform arbitrary actions including file modification, network requests, and code execution.
Identifies plugins missing the required `openclaw.plugin.json` manifest or with invalid manifest structure.
### Risks
- Malicious plugins can execute arbitrary code.
- Plugins without manifests may not load correctly.
- Vulnerable plugins may expose sensitive data.
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
Restrict permissions to the minimum required:
chmod 750 ~/.openclaw
chmod 640 ~/.openclaw/config.yaml
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
Restrict permissions to the minimum required:
chmod 750 ~/.openclaw
chmod 640 ~/.openclaw/config.yaml
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
Restrict permissions to the minimum required:
chmod 750 ~/.openclaw
chmod 640 ~/.openclaw/config.yaml
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
Restrict permissions to the minimum required:
chmod 750 ~/.openclaw
chmod 640 ~/.openclaw/config.yaml
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
Restrict permissions to the minimum required:
chmod 750 ~/.openclaw
chmod 640 ~/.openclaw/config.yaml
The document includes plugin removal and configuration reset commands as direct remediation steps without warning that they may remove installed components or discard local configuration. In a setup/security validation skill, users may copy-paste these commands during troubleshooting, increasing the risk of unintended data loss or service disruption.
Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.
# Check OpenClaw directory
if os.path.exists(OPENCLAW_DIR):
openclaw_mode = os.stat(OPENCLAW_DIR).st_mode
if openclaw_mode & 0o022: # World-writable
issues.append({
"check": "Excessive Permissions",
"description": f"OpenClaw directory has excessive permissions: {oct(openclaw_mode)}.",
Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.
# Check OpenClaw directory
if os.path.exists(OPENCLAW_DIR):
openclaw_mode = os.stat(OPENCLAW_DIR).st_mode
if openclaw_mode & 0o022: # World-writable
issues.append({
"check": "Excessive Permissions",
"description": f"OpenClaw directory has excessive permissions: {oct(openclaw_mode)}.",
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
issues.append({
"check": "Excessive Permissions",
"description": f"OpenClaw directory has excessive permissions: {oct(openclaw_mode)}.",
"fix": "Run `chmod 750 ~/.openclaw` to restrict permissions."
})
# Check config file
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
issues.append({
"check": "Excessive Permissions",
"description": f"OpenClaw directory has excessive permissions: {oct(openclaw_mode)}.",
"fix": "Run `chmod 750 ~/.openclaw` to restrict permissions."
})
# Check config file
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
issues.append({
"check": "Excessive Permissions",
"description": f"Config file has excessive permissions: {oct(config_mode)}.",
"fix": "Run `chmod 640 ~/.openclaw/config.yaml` to restrict permissions."
})
return issues
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
# OpenClaw is distributed via npm, not pip
try:
result = subprocess.run(
["npm", "list", "-g", "openclaw", "--json"],
capture_output=True,
text=True,
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
if data.get('dependencies', {}).get('openclaw'):
version = data['dependencies']['openclaw'].get('version', 'unknown')
# Check against latest
latest_result = subprocess.run(
["npm", "view", "openclaw", "version"],
capture_output=True,
text=True,
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
except FileNotFoundError:
# npm not found - check if openclaw command exists
try:
result = subprocess.run(
["openclaw", "--version"],
capture_output=True,
text=True,
Presenting global update commands without cautions can cause system-wide changes, version drift, or compatibility issues with existing plugins and workflows. While not inherently malicious, this is risky in security guidance because users may apply updates blindly and destabilize their environment.