T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/fetch.py:13
- Finding
- TLS Certificate Verification Disabled for All HTTPS Requests<![CDATA[ ## Vulnerability Details **File Location**: `scripts/fetch.py:13-16`; `scripts/smart-url.py:13-16` **Vulnerability Type**: Improper certificate validation **Risk Level**: High ### Vulnerable Code `scripts/fetch.py:13-16`: ```python # Ignore SSL verification ssl_context = ssl.create_default_context() ssl_context.check_hostname = False ssl_context.verify_mode = ssl.CERT_NONE ``` `scripts/smart-url.py:13-16`: ```python # Ignore SSL verification (required by some services) ssl_context = ssl.create_default_context() ssl_context.check_hostname = False ssl_context.verify_mode = ssl.CERT_NONE ``` The unverified context is subsequently passed to `urllib.request.urlopen`, including in `scripts/fetch.py:98` and `scripts/smart-url.py:55`. ### Technical Analysis Both scripts explicitly disable certificate-chain validation and hostname verification. Consequently, HTTPS provides encryption without reliable endpoint authentication. Any certificate—including a self-signed certificate or one issued for a different hostname—will be accepted. An attacker capable of intercepting network traffic can impersonate the requested website or one of the external conversion services and return arbitrary content. The returned content is treated as a successfully fetched article and may later be written into an Obsidian note. Certificate verification is disabled globally for all requests made with this context rather than being limited to a narrowly scoped compatibility exception. ### Attack Path 1. A user invokes the Skill to retrieve an HTTPS article. 2. The script connects to a conversion service or directly to the original website. 3. An attacker with an on-path position intercepts the connection. 4. The attacker presents an arbitrary or self-signed certificate. 5. The script accepts the certificate because hostname and certificate verification are disabled. 6. The attacker supplies modified Markdown or HTML. 7. The forged content is returned as successful output and ...[truncated 541 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions - Remove both insecure SSL overrides: - `ssl_context.check_hostname = False` - `ssl_context.verify_mode = ssl.CERT_NONE` - Use Python’s default verified TLS context: ```python ssl_context = ssl.create_default_context() ``` - Do not silently fall back to unverified TLS when certificate validation fails. - Return a clear error identifying the affected service and certificate problem. - Ensure the runtime has a current CA trust store. - If private certificate authorities must be supported, load only the explicitly trusted CA certificate with `ssl.create_default_context(cafile=...)`. - Consider enforcing a minimum TLS version appropriate for the deployment environment. ]]>
