T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/clone_and_index.py:79
- Finding
- GitLab API token transmitted without TLS certificate verification<![CDATA[ ## Vulnerability Details **File Location**: `scripts/clone_and_index.py`, lines 79-96 **Vulnerability Type**: Disabled TLS certificate and hostname verification **Risk Level**: High ### Vulnerable Code ```python def _make_ssl_ctx(): """Create a permissive SSL context (many internal GitLabs use self-signed certs).""" ctx = ssl.create_default_context() ctx.check_hostname = False ctx.verify_mode = ssl.CERT_NONE return ctx _SSL_CTX = _make_ssl_ctx() def api_get(gitlab_url: str, token: str, path: str, params: dict | None = None) -> list | dict: """GET request to GitLab API. Returns parsed JSON.""" url = f"{gitlab_url}/api/v4{path}" if params: url += "?" + urllib.parse.urlencode(params) req = urllib.request.Request(url, headers={"PRIVATE-TOKEN": token}) try: with urllib.request.urlopen(req, context=_SSL_CTX, timeout=30) as resp: ``` ### Technical Analysis The global SSL context disables both certificate-chain validation and hostname verification. Every GitLab API call uses this context while sending the personal access token in the `PRIVATE-TOKEN` request header. Consequently, the client cannot authenticate the GitLab server. A network-positioned adversary can present an arbitrary certificate without triggering an error. This defeats HTTPS server authentication and permits interception or modification of API traffic. The recursive subgroup and project requests are necessary for the declared batch-cloning functionality and are scoped to user-selected groups. The vulnerability is not the API access itself, but the insecure transport configuration used for all such access. ### Attack Path 1. The user supplies a token with the documented `read_api` and `read_repository` scopes. 2. The Skill connects to the configured GitLab URL over a network controlled or observable by an attacker. 3. The attacker intercepts the connection and presents an untrusted certificate. 4. Because certificate and hostnam ...[truncated 952 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions - Retain the secure defaults from `ssl.create_default_context()`: - Do not set `check_hostname` to `False`. - Do not set `verify_mode` to `ssl.CERT_NONE`. - For internal GitLab installations using a private certificate authority, support an explicit CA bundle setting and load it using: ```python ctx = ssl.create_default_context() ctx.load_verify_locations(cafile=configured_ca_bundle) ``` - Reject non-HTTPS GitLab URLs unless an explicit, strongly warned development-only override is enabled. - Validate the URL scheme and hostname before transmitting the token. - Do not silently fall back to insecure TLS behavior after a certificate error. - Add tests asserting that the SSL context uses `ssl.CERT_REQUIRED` and that hostname verification remains enabled. - Document private-CA installation as the supported solution for self-signed or enterprise certificates. ]]>
