T09 · Insecure Skill Coding Practices
- Location
scripts/nightscout_read.py:11- Finding
Unrestricted Nightscout Base URL Enables SSRF and Insecure Transport
- Content
View full analysis
str: base = (sys.argv[sys.argv.index('--url') + 1] if '--url' in sys.argv and sys.argv.index('--url') + 1 < len(sys.argv) else None) or None if not base: import os base = os.environ.get('NIGHTSCOUT_BASE_URL') if not base: base = DEFAULT_BASE_URL return base.rstrip('/') + '/' def fetch_json(path: str): url = urllib.parse.urljoin(get_base_url(), path) req = urllib.request.Request(url, headers={'User-Agent': 'OpenClaw nightscout-local'}) with urllib.request.urlopen(req, timeout=20) as resp: return json.loads(resp.read().decode('utf-8')) ``` ### Technical Analysis The script accepts the base URL directly from the `--url` command-line argument or the `NIGHTSCOUT_BASE_URL` environment variable and passes the resulting URL to `urllib.request.urlopen`. It does not validate the URL scheme, hostname, resolved IP address, port, or redirect destination. An attacker able to influence either input can direct requests toward loopback, private-network, link-local, or otherwise privileged destinations reachable from the Agent's network context. Although the requested Nightscout API paths are fixed by the selected operation, an internal or attacker-controlled server can expose data at those paths or redirect the request to another destination. Python's default URL handling may follow HTTP redirects, and redirect targets are not revalidated. The script also permits plaintext HTTP. Glucose readings and related medical information can therefore be intercepted or altered by a network-positioned attacker. The returned JSON may be presented as legitimate Nightscout data. The response body is read without a maximum size, allowing a malicious server to return a very large response ...[truncated 1469 chars]- Remediation
View remediation
