T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/auto_publish.py:506
- Finding
- WordPress credentials transmitted over connections with disabled TLS verification<![CDATA[ ## Vulnerability Details **File Location**: `scripts/auto_publish.py:506-511` **Vulnerability Type**: Improper certificate validation during authenticated CMS upload **Risk Level**: High ### Vulnerable Code ```python if use_ssl: ctx = ssl.create_default_context() ctx.check_hostname = False ctx.verify_mode = ssl.CERT_NONE conn = httplib.HTTPSConnection(host, port, timeout=60, context=ctx) else: conn = httplib.HTTPConnection(host, port, timeout=60) ``` The resulting connection is used with headers constructed at `scripts/auto_publish.py:493-499`: ```python headers = { "Authorization": self.auth_header, "Content-Type": content_type, "Content-Disposition": f'attachment; filename="{filename}"', "User-Agent": "Mozilla/5.0 (compatible; OpenClaw-AutoPublisher/1.0)", "Connection": "close", "Content-Length": str(len(file_data)), } ``` ### Technical Analysis The image-upload implementation explicitly disables both certificate-chain validation and hostname verification for every HTTPS upload. Consequently, the client cannot verify that it is connected to the configured WordPress server. The request carries an HTTP Basic authorization header derived from the WordPress username and application password. Base64 encoding at `scripts/auto_publish.py:405-406` is the normal representation required by HTTP Basic authentication and is not encryption. Although the encoded credential is not printed to stdout, it is exposed if the upload connection is intercepted. The code also permits a CMS URL using plain HTTP, in which case the same credential is sent without transport encryption. Neither behavior is necessary for the declared publishing functionality and violates least-privilege credential handling. ### Attack Path 1. A user configures the Skill with a WordPress URL and supplies a valid application password through the environment. 2. The publishing pipeline prepares an image upload containing the Basic authorization ...[truncated 1319 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Remove the certificate-verification bypass and use a normal verified TLS context: ```python if use_ssl: ctx = ssl.create_default_context() conn = httplib.HTTPSConnection(host, port, timeout=60, context=ctx) else: raise ValueError("CMS publishing requires HTTPS") ``` 2. Reject non-HTTPS CMS URLs before loading or transmitting credentials. 3. If private certificate authorities must be supported, add an explicit configuration option for a trusted CA bundle rather than using `ssl.CERT_NONE`. 4. Do not provide a general-purpose insecure mode. If a development-only override is unavoidable, require explicit per-run consent, display a strong warning, and prohibit its use with real credentials. 5. Use a dedicated WordPress service account with only the capabilities required to create posts and upload media. 6. Rotate the application password after deploying the fix if the vulnerable upload path has been used on an untrusted network. 7. Apply the same HTTPS requirement and destination validation to `scripts/publish.py` and custom CMS publishing paths. ]]>
