T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/rewrite.py:17
- Finding
- TLS Certificate and Hostname Verification Disabled## Vulnerability Details **File Location**: `scripts/rewrite.py`, lines 17–20 and line 40 **Vulnerability Type**: Improper TLS certificate validation **Risk Level**: High ### Vulnerable Code ```python # Skip self-signed certificate verification (temporary workaround) SSL_CONTEXT = ssl.create_default_context() SSL_CONTEXT.check_hostname = False SSL_CONTEXT.verify_mode = ssl.CERT_NONE ``` The insecure context is subsequently used for the request: ```python resp = urllib.request.urlopen(req, context=SSL_CONTEXT, timeout=200) ``` ### Technical Analysis The script explicitly disables both certificate-chain validation and hostname verification. Consequently, TLS encrypts the connection but does not authenticate the remote service at `https://192.144.154.90/demo/a2m/resource`. Because `ssl.CERT_NONE` accepts an arbitrary server certificate and `check_hostname = False` prevents endpoint identity validation, an attacker capable of intercepting network traffic can present any certificate and impersonate the configured service. The client will then transmit the user-supplied paper to the attacker's endpoint. The same weakness also allows the attacker to forge service responses. This includes ordinary rewrite results and HTTP 402 responses containing attacker-controlled `Payment-Needed` headers and JSON details. Although the local script does not execute payment itself, downstream agents or integrations could rely on this unauthenticated payment metadata. ### Attack Path 1. A user submits paper content through the skill. 2. The script creates a POST request containing the content as JSON. 3. An attacker with a network interception position redirects or intercepts traffic to the configured IP address. 4. The attacker presents a self-signed or otherwise untrusted TLS certificate. 5. The script accepts that certificate because certificate and hostname verification are disabled. 6. The attacker receives the submitted p ...[truncated 796 chars]
- Remediation
- ## Remediation Suggestions 1. Deploy the service under a stable DNS hostname with a certificate issued by a trusted certificate authority. 2. Remove the custom context that disables verification and use Python's secure defaults: ```python SSL_CONTEXT = ssl.create_default_context() resp = urllib.request.urlopen( req, context=SSL_CONTEXT, timeout=200, ) ``` Alternatively, omit the `context` argument so `urlopen` uses the default validated TLS context. 3. Do not set `verify_mode` to `ssl.CERT_NONE` or disable `check_hostname` in production. 4. If a private certificate authority is required, install its CA certificate explicitly and configure the context with `cafile`; do not disable validation globally. 5. If connecting by IP is unavoidable, use a certificate whose subject alternative name includes that IP address and retain full certificate verification. 6. Treat all HTTP response bodies and payment-related headers as untrusted input. Validate their schema, expected issuer, destination, amount, and transaction context before downstream processing. 7. Consider certificate or public-key pinning only as an additional control with a documented key-rotation process, not as a substitute for standard TLS validation.
