Back to skill

Security audit

Auto-Claw

Security checks for vulnerabilities and agentic risk

Overview

This WordPress automation skill is coherent in purpose, but it gives agents high-impact site and server control with unsafe command execution and weak approval safeguards.

Install only after reviewing the code and running it in a constrained environment. Use a least-privilege WordPress/service account, require HTTPS, remove --allow-root and shell=True command construction, pin SSH host keys, replace the demo approval stubs with a real fail-closed approval system, and treat cron jobs or mu-plugin deployment as persistent changes that need explicit approval and rollback steps.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (5)

T09 · Insecure Skill Coding Practices

Error
Location
src/wordpress.py:18
Finding

Root-Capable OS Command Injection Through Shell-Interpolated Inputs

Content
View full analysis
tuple[str, str, int]: """Execute command locally through subprocess or remotely through SSH.""" if self.ssh_host == "localhost" or self.ssh_host in ("127.0.0.1", ""): # Local mode: execute directly result = subprocess.run( cmd, shell=True, capture_output=True, text=True, timeout=60 ) return result.stdout.strip(), result.stderr.strip(), result.returncode else: # Remote mode: execute through SSH full_cmd = f"cd {self.web_root} && {cmd}" result = subprocess.run( ["ssh", "-i", self.ssh_key, "-o", "StrictHostKeyChecking=no", f"{self.ssh_user}@{self.ssh_host}", full_cmd], capture_output=True, text=True, timeout=60 ) return result.stdout.strip(), result.stderr.strip(), result.returncode def _wp(self, args: str) -> tuple[str, str, int]: """Execute WP-CLI command.""" return self._ssh( f"WP_CLI_PHP={self.php_bin} /usr/local/bin/wp " f"--allow-root --path={self.web_root} {args}" ) ``` Additional affected construction in `src/seo.py`: ```python def _wp(self, args: str) -> Tuple[str, str, int]: """Execute WP-CLI command.""" if not self.wp_web_root: return "", "No web root configured", 1 cmd = ( f"cd {self.wp_web_root} && " f"WP_CLI_PHP={self.php_bin} " f"{self.wp_cli} --allow-root {args}" ) r = subprocess.run( cmd, shell=True, capture_output=True, text=True, timeout=60 ) return r.stdout.strip(), r.std ...[truncated 2561 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
src/pipeline.py:41
Finding

Approval Pipeline Automatically Approves High-Risk Operations

Content
View full analysis
bool: """Default approval logic - demonstration only.""" return True # Production should send a webhook and wait for approval def request(self, op: Operation) -> GateDecision: """Request operation execution and return the decision.""" risk = self.assess_risk(op.action) if risk == RiskLevel.LOW: decision = GateDecision( "allow", "LOW risk - auto approved", op.id ) elif risk == RiskLevel.MEDIUM: approved = self.approval_callback(op) if approved: decision = GateDecision( "allow", "MEDIUM risk - manually approved", op.id ) else: decision = GateDecision( "need_approval", "Waiting for approval", op.id ) else: approved = self.approval_callback(op) if approved: decision = GateD ...[truncated 2781 chars]
Remediation
View remediation
bool: return False ``` 2. Return `need_approval` when no authenticated approval provider is configured. 3. Store pending operations in durable storage with: - Operation ID. - Canonical action and resource. - Cryptographic hash of all parameters. - Requesting identity. - Creation and expiration times. - Approval state and approver identity. 4. Require an authenticated, authorization-checked approval action. 5. Bind approval to the exact immutable operation hash so parameters cannot change after review. 6. Make approvals single-use and expire them after a short period. 7. Require separate approval for retries of destructive operations. 8. Ensure audit messages accurately distinguish automatic policy decisions from human approvals. 9. Remove or fully implement the unconditional `approve_operation()` stub. 10. Add tests proving that MEDIUM and HIGH operations are blocked when no approval backend is configured. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
src/wordpress.py:24
Finding

SSH Host-Key Verification Is Disabled

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
lib/wordpress/client.py:25
Finding

WordPress Basic Authentication Credentials Can Be Sent Over Plaintext HTTP

Content
View full analysis
Dict[str, Any]: """Send an HTTP request.""" url = urljoin(self.site_url + "/", endpoint.lstrip("/")) self.audit.log("wordpress", "request", { "method": method, "url": url, "username": self.username }) response = self._session.request(method, url, **kwargs) response.raise_for_status() return response.json() ``` The client performs no scheme validation, while the project documentation includes HTTP WordPress URLs, including `SKILL.md:46-50` and `SKILL.md:72`. ### Technical Analysis The Requests session is configured for HTTP Basic Authentication. Basic Authentication is only an encoding of the username and password, not encryption. If `site_url` uses `http://`, the Authorization header and authenticated traffic are sent without transport confidentiality or integrity. The client does not: - Require HTTPS. - Reject redirects from HTTPS to HTTP. - Pin an expected hostname or TLS policy. - Warn before sending credentials over an insecure scheme. Because the documented examples normalize HTTP deployment, operators may reasonably configure the REST client with an insecure URL. ### Attack Path 1. An operator configures `WordPressClient` with an ...[truncated 956 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
requirements.txt:1
Finding

Python Dependencies Are Open-Ended and Lack Integrity Pinning

Content
View full analysis
=2.31.0 python-dotenv>=1.0.0 hvac>=1.1.0 # HashiCorp Vault client pydantic>=2.0.0 ``` ### Technical Analysis Each dependency has only a minimum version and no upper bound, exact lock, or package hash. A future installation can therefore resolve to package versions that were not present during this audit. No suspicious package names, typo-squatted dependencies, or untrusted package indexes were identified. The issue is the absence of reproducible and integrity-checked dependency resolution rather than evidence that a currently declared package is malicious. This is particularly relevant because `hvac` participates in secret retrieval, `requests` handles authenticated network traffic, and the dependencies execute with the same privileges as Auto-Claw. ### Attack Path 1. A deployment installs dependencies at a later date using `pip install -r requirements.txt`. 2. The package resolver selects the newest versions satisfying the open-ended constraints. 3. A newly released, compromised, or unexpectedly incompatible package is downloaded. 4. Package installation or import executes code that was not part of the reviewed dependency set. 5. That code inherits Auto-Claw's filesystem, network, environment, and potentially root privileges. This is a supply-chain exposure scenario; the audit did not find evidence that it is currently being actively exploited. ### Impact Assessment A compromised or unsafe future dependency could: - Access WordPress and Vault credentials in environment variables or process memory. - Modify WordPress files and content. - Intercept authenticated HTTP or Vault traffic. - Execute arbitrary code with the Auto-Claw process privileges. - Produce inconsistent behavior across deployments. ...[truncated 157 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (215)

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% confidence
Finding

Using --allow-root causes WP-CLI operations to run with root-level trust, sharply increasing blast radius if the command path is abused or if the agent performs unintended actions. In combination with shell execution and WordPress admin actions, mistakes or compromise could modify site files, plugins, content, or broader system state.

Content

Scanner excerpt · demo_local.py (reported line 25)May include surrounding context.

python
def wp_cmd(args: str) -> tuple:
    """执行 WP-CLI 命令,返回 (stdout, stderr, returncode)"""
    cmd = f"cd {WEB_ROOT} && WP_CLI_PHP={PHP_BIN} {WP_CLI} --allow-root {args}"
    result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=60)
    return result.stdout.strip(), result.stderr.strip(), result.returncode

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
98% confidence
Finding

This is a true tool-parameter abuse issue because the script turns dynamically assembled text into a shell command, allowing command expansion beyond intended WP-CLI behavior. In an agent context, any future path that lets model-controlled or user-controlled text reach args could escalate to arbitrary system command execution.

Content

Scanner excerpt · demo_local.py (reported line 26)May include surrounding context.

python
def wp_cmd(args: str) -> tuple:
    """执行 WP-CLI 命令,返回 (stdout, stderr, returncode)"""
    cmd = f"cd {WEB_ROOT} && WP_CLI_PHP={PHP_BIN} {WP_CLI} --allow-root {args}"
    result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=60)
    return result.stdout.strip(), result.stderr.strip(), result.returncode

def print_header(title):

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
92% confidence
Finding

Using wp with --allow-root normalizes privileged execution of WordPress management commands and removes a built-in safety check intended to discourage root-level operation. In an agent or automation context, this increases blast radius: a path mistake, malicious plugin source, or command injection elsewhere could modify the site or filesystem with full privileges.

Content

Scanner excerpt · docs/performance-deployment-20260324.md (reported line 116)May include surrounding context.

md
WEB_ROOT="/www/wwwroot/linghangyuan1234.dpdns.org"
PHP_BIN="/www/server/php/82/bin/php"
WP_CLI="/usr/local/bin/wp"
WP="$PHP_BIN $WP_CLI --allow-root --path=$WEB_ROOT"

echo "🚀 开始性能优化..."

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
91% confidence
Finding

Using WP-CLI with --allow-root disables a built-in safety guard and normalizes privileged execution for content and plugin changes. In an agent-driven or automated pipeline, this raises the blast radius of mistakes or prompt/tool abuse because any malformed or unintended WP-CLI command would execute with full root privileges against the target site.

Content

Scanner excerpt · docs/seo-deployment-20260324.md (reported line 56)May include surrounding context.

md
# auto-claw-seo-fix.sh
# Auto-Claw Generated SEO Fixes

WP_CLI="/www/server/php/82/bin/php /usr/local/bin/wp --allow-root --path=/www/wwwroot/linghangyuan1234.dpdns.org"

# Post ID 8 - OpenClaw Auto
$WP_CLI post meta update 8 _yoast_wpseo_title 'OpenClaw Auto | AI驱动WordPress运营平台'

Missing User Warnings

High
Category
Not specified by scanner
Confidence
93% confidence
Finding

Deleting content from a WordPress site is a destructive operation, and the 'force' parameter can bypass the trash for irreversible removal. The method has only a developer-oriented docstring and no confirmation step, visible warning, or other user disclosure about the impact of the deletion.

Content

No source excerpt is available for this finding.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
75% confidence
Finding

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).

Content

Scanner excerpt · scripts/weekly-report.sh (reported line 47)May include surrounding context.

sh
foreach ($by_event as $event => $count) {
    echo "   - $event: $count\n";
}
' --allow-root 2>/dev/null
echo ""

# 4. Beta Applications

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
75% confidence
Finding

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).

Content

Scanner excerpt · scripts/weekly-report.sh (reported line 72)May include surrounding context.

sh
foreach ($by_event as $event => $count) {
    echo "   - $event: $count\n";
}
' --allow-root 2>/dev/null
echo ""

# 4. Beta Applications

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
75% confidence
Finding

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).

Content

Scanner excerpt · scripts/weekly-report.sh (reported line 77)May include surrounding context.

sh
foreach ($by_event as $event => $count) {
    echo "   - $event: $count\n";
}
' --allow-root 2>/dev/null
echo ""

# 4. Beta Applications

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
75% confidence
Finding

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).

Content

Scanner excerpt · src/image_optimizer.py (reported line 79)May include surrounding context.

python
foreach ($by_event as $event => $count) {
    echo "   - $event: $count\n";
}
' --allow-root 2>/dev/null
echo ""

# 4. Beta Applications

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The approval function logs the request and then unconditionally returns True for any supplied operation ID, bypassing any real validation of pending state, requester identity, or authorization. In an agent that gates write operations to WordPress, this can completely nullify the intended approval control and allow unauthorized sensitive actions if this method is exposed through a higher layer.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
95% confidence
Finding

The code constructs a curl command containing credential-bearing access details, including reading a local .htpasswd path for admin authentication material. Even though the command is not executed here, embedding hidden credential access logic in the skill is highly sensitive and suggests intent to use privileged secrets without transparent disclosure, which is especially risky in an agent-executed environment.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

Both web_root and args are inserted into a shell command without escaping or validation, creating a straightforward command injection path. Because the command also changes directories and invokes WP-CLI as root-capable, successful exploitation could lead to arbitrary command execution and compromise of the WordPress host.

Content

No source excerpt is available for this finding.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% confidence
Finding

The use of --allow-root causes WP-CLI actions to run with elevated privileges, increasing the consequences of any misuse or injection flaw in the surrounding command construction. While not exploitable by itself, in this context it materially worsens the command injection risk and may permit filesystem or WordPress configuration changes as root.

Content

Scanner excerpt · src/cache_optimizer.py (reported line 87)May include surrounding context.

python
def _run_wp(self, args: str) -> Tuple[str, str, int]:
        if not self.web_root:
            return "", "", 1
        cmd = f"cd {self.web_root} && WP_CLI_PHP={self.php_bin} {self.wp_cli} --allow-root {args}"
        r = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=60)
        return r.stdout.strip(), r.stderr.strip(), r.returncode

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
98% confidence
Finding

This is a tool-parameter abuse issue because the subprocess invocation hands attacker-controllable values to a shell interpreter. In an agent or automation context, this is especially dangerous because the tool boundary is crossed with minimal validation, enabling arbitrary OS command execution instead of only the intended WP-CLI actions.

Content

Scanner excerpt · src/cache_optimizer.py (reported line 88)May include surrounding context.

python
if not self.web_root:
            return "", "", 1
        cmd = f"cd {self.web_root} && WP_CLI_PHP={self.php_bin} {self.wp_cli} --allow-root {args}"
        r = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=60)
        return r.stdout.strip(), r.stderr.strip(), r.returncode
    
    def _detect_current_cache(self):

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · src/exit_intent.py (reported line 129)May include surrounding context.

python
page_types=page_types or ["cart", "checkout"]
        )
        self.rules[rule_id] = rule
        return rule
    
    def assign_offer_to_rule(self, rule_id: str, offer_id: str):
        """将优惠分配给规则"""

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · src/journey_personalizer.py (reported line 153)May include surrounding context.

python
page_types=page_types or ["cart", "checkout"]
        )
        self.rules[rule_id] = rule
        return rule
    
    def assign_offer_to_rule(self, rule_id: str, offer_id: str):
        """将优惠分配给规则"""

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
97% confidence
Finding

This is the same underlying issue as the AST4 finding at line 80: a tool invocation is constructed from unsanitized parameters and executed via the shell. In a skill that may automate administrative WordPress operations, this context increases danger because successful injection could lead to arbitrary command execution, site compromise, or server takeover.

Content

Scanner excerpt · src/image_optimizer.py (reported line 80)May include surrounding context.

python
def _wp(self, args: str) -> Tuple[str, str, int]:
        cmd = f"cd {self.web_root} && WP_CLI_PHP={self.php_bin} {self.wp_cli} --allow-root {args}"
        r = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=60)
        return r.stdout.strip(), r.stderr.strip(), r.returncode
    
    def scan_images(self, max_depth: int = 3) -> List[ImageInfo]:

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
88% confidence
Finding

Running WP-CLI with --allow-root increases the blast radius of any misuse or injection by executing administrative operations with elevated privileges. In combination with generic argument forwarding, this can turn a diagnostic helper into a high-impact host and application control primitive.

Content

Scanner excerpt · src/performance_diag.py (reported line 68)May include surrounding context.

python
def _wp(self, args: str) -> Tuple[str, str, int]:
        if not self.web_root:
            return "", "No web root", 1
        cmd = f"cd {self.web_root} && WP_CLI_PHP={self.php_bin} {self.wp_cli} --allow-root {args}"
        r = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=60)
        return r.stdout.strip(), r.stderr.strip(), r.returncode

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
98% confidence
Finding

This is a classic tool-parameter abuse issue: subprocess.run with shell=True executes a command string assembled from multiple variables. In an agent setting, if any upstream prompt, config, or tool parameter can influence those fields, an attacker can steer the tool into arbitrary command execution on the host.

Content

Scanner excerpt · src/performance_diag.py (reported line 69)May include surrounding context.

python
if not self.web_root:
            return "", "No web root", 1
        cmd = f"cd {self.web_root} && WP_CLI_PHP={self.php_bin} {self.wp_cli} --allow-root {args}"
        r = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=60)
        return r.stdout.strip(), r.stderr.strip(), r.returncode
    
    def measure_ttfb(self, url: str) -> float:

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The file-level documentation says write operations require risk assessment and approval, but the default approval path returns True unconditionally. As a result, medium- and high-risk operations such as plugin installs, theme updates, deletes, and SQL execution are automatically allowed whenever a caller does not supply a real approval callback, defeating the security gate and creating a fail-open authorization bypass.

Content

No source excerpt is available for this finding.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
84% confidence
Finding

Using WP-CLI with --allow-root weakens a safety guard and increases the blast radius of any misuse or injection in the command path. If command execution is compromised, the operation may run with elevated privileges over the WordPress installation, enabling destructive changes, data exposure, or persistence.

Content

Scanner excerpt · src/seo.py (reported line 81)May include surrounding context.

python
"""执行 WP-CLI 命令"""
        if not self.wp_web_root:
            return "", "No web root configured", 1
        cmd = f"cd {self.wp_web_root} && WP_CLI_PHP={self.php_bin} {self.wp_cli} --allow-root {args}"
        r = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=60)
        return r.stdout.strip(), r.stderr.strip(), r.returncode

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
99% confidence
Finding

Executing a dynamically constructed shell command via subprocess.run(..., shell=True) is a classic tool-parameter abuse issue because it turns command parameters into executable shell syntax. In this context, the helper is reusable and can become an RCE primitive anywhere _wp() is called with tainted input.

Content

Scanner excerpt · src/seo.py (reported line 82)May include surrounding context.

python
if not self.wp_web_root:
            return "", "No web root configured", 1
        cmd = f"cd {self.wp_web_root} && WP_CLI_PHP={self.php_bin} {self.wp_cli} --allow-root {args}"
        r = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=60)
        return r.stdout.strip(), r.stderr.strip(), r.returncode
    
    def get_site_url(self) -> str:

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
99% confidence
Finding

This is a strong true positive for tool-parameter abuse because the client exposes many methods that feed untrusted text into a shell-backed execution primitive. Inputs such as title, content, json_ld, plugin_slug, plugin_name, author, status, php_bin, and web_root can be weaponized to execute arbitrary OS commands locally, which is especially dangerous in an agent skill that may process model- or user-generated content.

Content

Scanner excerpt · src/wordpress.py (reported line 21)May include surrounding context.

python
"""执行命令。本地模式用subprocess,远程用SSH"""
        if self.ssh_host == "localhost" or self.ssh_host in ("127.0.0.1", ""):
            # 本地模式:直接执行
            result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=60)
            return result.stdout.strip(), result.stderr.strip(), result.returncode
        else:
            # 远程模式:通过SSH

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
88% confidence
Finding

Using WP-CLI with --allow-root increases the blast radius of every command-execution bug and operational mistake in this client. In the context of multiple injection surfaces and plugin/file-management features, successful exploitation can lead to full site and likely host compromise rather than limited WordPress-only damage.

Content

Scanner excerpt · src/wordpress.py (reported line 35)May include surrounding context.

python
def _wp(self, args: str) -> tuple[str, str, int]:
        """通过 WP-CLI 执行命令"""
        return self._ssh(f"WP_CLI_PHP={self.php_bin} /usr/local/bin/wp --allow-root --path={self.web_root} {args}")
    
    def test_connection(self) -> bool:
        """测试连接"""

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The natural-language content, headings, and inline comments force a specific language/locale presentation without offering an alternative or documenting that the skill is intended only for a Chinese-speaking audience. This matches the policy category for language or locale constraints without user opt-in.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.