Back to skill

Security audit

WooCommerce Order Guard

Security checks for vulnerabilities and agentic risk

Overview

This skill matches its stated WooCommerce automation purpose, but it automatically changes live order address data using stored API credentials without enough safeguards.

Review before installing in production. Use a least-privilege WooCommerce API key, require an HTTPS store URL, protect the credentials file, test on staging first, and consider adding a dry-run/apply mode plus response checks before allowing automatic address updates.

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/order-guard.py:57
Finding
WooCommerce credentials and customer data may be transmitted without secure transport<![CDATA[ ## Vulnerability Details **File Location**: `scripts/order-guard.py`, lines 57–77 **Vulnerability Type**: Unvalidated network destination and failure to enforce HTTPS **Risk Level**: High ### Vulnerable Code ```python creds = load_creds(args.creds) url = creds['url'] auth = (creds['consumerKey'], creds['consumerSecret']) alerted_orders = load_storage(args.storage) resp = requests.get(f"{url}/wp-json/wc/v3/orders?status=processing&per_page=20", auth=auth) resp.raise_for_status() orders = resp.json() new_orders = [o for o in orders if o['id'] not in alerted_orders] if not new_orders: print("HEARTBEAT_OK") return for order in new_orders: order_id = order['id'] shipping = order.get('shipping', {}) if not shipping.get('address_1'): update_data = {"shipping": copy_billing_to_shipping(order)} requests.put(f"{url}/wp-json/wc/v3/orders/{order_id}", auth=auth, json=update_data) ``` ### Technical Analysis The script obtains the WooCommerce server URL from a local JSON configuration file and uses it directly to construct authenticated GET and PUT requests. It does not validate the URL scheme or destination. The requests use WooCommerce consumer credentials through HTTP Basic authentication. If the configured URL uses plain HTTP, those credentials and the associated WooCommerce traffic are not protected against interception or modification by an on-path attacker. Order responses can include customer personal information, while update requests contain customer names and postal addresses. A user or process capable of modifying the credentials file can also replace the configured URL with an attacker-controlled destination. The script will then disclose the configured API credentials to that server in an authenticated request. Although network access is necessary for the declared WooCommerce functionality, permitting arbitrary or unencrypted destinations is broader than the minimum safe privilege required. ### Attack Pat ...[truncated 1279 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Parse the configured URL with `urllib.parse.urlparse` and reject every scheme except `https`. 2. Reject URLs containing embedded user information, fragments, or malformed hostnames. 3. Where the deployment model permits it, require the hostname to match an explicit trusted-store allowlist. 4. Use a WooCommerce API key restricted to only the permissions required to read and update orders. 5. Protect `woo-api.json` with restrictive filesystem permissions, such as owner read/write only. 6. Add finite connection and response timeouts to every request. 7. Consider creating a configured `requests.Session` with explicit TLS verification and a controlled redirect policy. 8. Do not disable certificate verification. If private certificate authorities are required, configure a trusted CA bundle explicitly. Example validation: ```python from urllib.parse import urlparse parsed = urlparse(creds["url"]) if parsed.scheme != "https" or not parsed.hostname or parsed.username or parsed.password: raise ValueError("WooCommerce URL must be a valid HTTPS URL without embedded credentials") url = creds["url"].rstrip("/") ``` ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/order-guard.py:75
Finding
Failed shipping-address updates are recorded as successfully processed<![CDATA[ ## Vulnerability Details **File Location**: `scripts/order-guard.py`, lines 75–79 **Vulnerability Type**: Missing HTTP response validation before committing deduplication state **Risk Level**: Medium ### Vulnerable Code ```python if not shipping.get('address_1'): update_data = {"shipping": copy_billing_to_shipping(order)} requests.put(f"{url}/wp-json/wc/v3/orders/{order_id}", auth=auth, json=update_data) alerted_orders.append(order_id) print(f"NEW_ORDER_ID: {order_id}") ``` ### Technical Analysis The result of the order-update request is ignored. Unlike the preceding GET request, the PUT request does not call `raise_for_status()` or otherwise verify that WooCommerce accepted the shipping-address update. The order ID is appended to the persistent deduplication list regardless of whether the PUT operation returned an authorization error, validation error, server error, or another failure. Once storage is saved, subsequent executions filter out the order and do not retry the missing shipping-address repair. This creates a fail-open state transition: the script reports `NEW_ORDER_ID` and records the order as handled before confirming that its primary data-integrity operation succeeded. ### Attack Path 1. A processing order has an empty `shipping.address_1`. 2. The WooCommerce update fails because of a transient outage, insufficient API permissions, malformed customer data, a server-side validation error, or an intentionally induced error response. 3. The script ignores the failed PUT response. 4. It prints the new-order signal and adds the order ID to `alerted_orders`. 5. The deduplication file is saved. 6. Future runs exclude that order, so the missing shipping address is not repaired automatically even after the underlying failure is resolved. ### Impact Assessment This flaw does not directly grant additional system privileges. Its impact is on integrity and availability of the declared fulfillment safeguard. Orders may be treated as h ...[truncated 488 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Capture the PUT response and call `raise_for_status()` before recording the order as alerted. 2. Append the order ID to persistent state only after the update succeeds. 3. Add finite request timeouts and carefully bounded retries for transient failures. 4. Log failures without exposing API credentials or full customer address data. 5. Save state atomically to prevent corruption if execution stops while writing. 6. Consider maintaining separate states for successfully repaired orders, orders that already had shipping information, and retryable failures. Example: ```python if not shipping.get("address_1"): update_data = {"shipping": copy_billing_to_shipping(order)} update_response = requests.put( f"{url}/wp-json/wc/v3/orders/{order_id}", auth=auth, json=update_data, timeout=(5, 30), ) update_response.raise_for_status() alerted_orders.append(order_id) print(f"NEW_ORDER_ID: {order_id}") ``` ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (5)

Intent-Code Divergence

High
Confidence
96% confidence
Finding
The docstring materially understates the script’s behavior by claiming it only fetches processing orders and emits alerts, while the implementation also performs authenticated remote updates to WooCommerce orders. This mismatch is dangerous because operators may deploy or approve the script under false assumptions, leading to unauthorized or unexpected modification of customer order records and shipping details.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill explicitly states that it will auto-fix missing shipping addresses by copying billing data into shipping fields, but the description does not prominently warn that this changes live WooCommerce order records. That omission can cause operators to run it in production without understanding that customer/order data will be modified automatically, increasing the risk of unintended fulfillment errors, privacy issues, and hard-to-trace data integrity problems.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The script automatically modifies order shipping data over authenticated HTTP without operator confirmation, approval workflow, or even checking the PUT response for success. In this skill context, the action touches real e-commerce order records and customer address data, so silent automation increases the chance of unintended data corruption, privacy issues, or propagation of bad billing data into shipping fields.

External Transmission

Medium
Category
Data Exfiltration
Content
if not shipping.get('address_1'):
            update_data = {"shipping": copy_billing_to_shipping(order)}
            requests.put(f"{url}/wp-json/wc/v3/orders/{order_id}", auth=auth, json=update_data)

        alerted_orders.append(order_id)
        print(f"NEW_ORDER_ID: {order_id}")
Confidence
80% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Low
Confidence
81% confidence
Finding
The script loads consumer credentials from a local file and uses them to authenticate WooCommerce API requests. While this is functionally necessary, the file does not provide a clear user-facing warning that sensitive credentials are being accessed and used for remote authenticated operations.

Static analysis

No suspicious patterns detected.