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("/") ``` ]]>
