T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/octoprint.py:35
- Finding
- OctoPrint API Credentials May Be Transmitted over Plaintext HTTP<![CDATA[ ## Vulnerability Details **File Location**: `scripts/octoprint.py:35-49`; insecure default in `config.example.json:2-3` **Vulnerability Type**: Plaintext transmission of an API credential **Risk Level**: High ### Vulnerable Code ```python def make_request(method, endpoint, **kwargs): """Make a request to Octoprint API""" config = load_config() url = f"{config['octoprint_url']}{endpoint}" headers = {"X-Api-Key": config["api_key"]} if "headers" in kwargs: kwargs["headers"].update(headers) else: kwargs["headers"] = headers try: response = requests.request(method, url, **kwargs, timeout=10) response.raise_for_status() ``` The example configuration explicitly recommends an unencrypted endpoint: ```json { "octoprint_url": "http://octopi.local", "api_key": "YOUR_API_KEY_HERE" } ``` The upload path repeats the same behavior at `scripts/octoprint.py:521-529`: ```python config = load_config() url = f"{config['octoprint_url']}/api/files/local" headers = {"X-Api-Key": config["api_key"]} with open(filepath, 'rb') as f: files = {'file': (filename, f, 'application/octet-stream')} response = requests.post(url, headers=headers, files=files, timeout=30) response.raise_for_status() ``` ### Technical Analysis The script places the OctoPrint API key in the `X-Api-Key` header without requiring HTTPS. Because the supplied example uses `http://octopi.local`, a normal installation based on that example transmits the credential and all printer commands without transport encryption. An attacker capable of observing or manipulating the local network can capture the API key, inspect uploaded G-code, alter API responses, or inject and replay control requests. The use of a `.local` hostname also makes endpoint integrity dependent on local name resolution and network trust. Authenticated network access is necessary for the declared OctoPrint functionality, but plaintext credential transport is no ...[truncated 1328 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Require `https://` for `octoprint_url` by default and reject plaintext HTTP unless the user explicitly enables a clearly documented compatibility override. 2. Replace the HTTP URLs in `config.example.json` with HTTPS examples. 3. Preserve TLS certificate verification and provide a documented way to trust a private CA rather than recommending `verify=False`. 4. Use a dedicated, least-privileged OctoPrint application key instead of an administrator-level key. 5. Warn prominently when an insecure endpoint is configured and require explicit confirmation before sending credentials. 6. Consider supporting environment variables or an operating-system secret store for the API key. 7. Apply the same validated URL construction to both `make_request()` and `upload_file()` so no secondary request path bypasses the transport policy. 8. Document network segmentation and advise users not to expose OctoPrint directly to untrusted networks. ]]>
