T09 · Insecure Skill Coding Practices
- Location
cli.py:61- Finding
Oura bearer token can be transmitted to an arbitrary network host
- Content
View full analysis
Dict[str, Any]: url = self.base_url.rstrip("/") + "/" + path.lstrip("/") # Oura V2 sometimes uses different base paths for detailed data # If the path is 'sleep' or 'readiness' or 'heartrate', it might be at /v2/usercollection/ # but let's check if we need to adjust based on the endpoint. headers = {"Authorization": f"Bearer {self.token}", "Accept": "application/json"} for attempt in range(self.max_retries + 1): try: resp = self._session.get(url, headers=headers, params=params, timeout=self.timeout_s) ``` The destination is selected without validation in each command, for example: ```python token, source = _load_token(args.env_file) base_url = args.base_url or os.getenv("OURA_BASE_URL") or DEFAULT_BASE_URL client = OuraClient(token=token, base_url=base_url, timeout_s=args.timeout) ``` The command-line option enabling this behavior is: ```python p.add_argument( "--base-url", help=f"Override API base URL (default: {DEFAULT_BASE_URL})", default=None, ) ``` ### Technical Analysis The CLI loads a sensitive OAuth bearer token and attaches it to every request through the `Authorization` header. However, the request destination can be replaced with an arbitrary value through either `--base-url` or the `OURA_BASE_URL` environment variable. There is no validation of: - The URL scheme. - Whether TLS is required. - The destination hostname. - Whether the hostname belongs to Oura. - URL user-information or unusual URL components. - Whether production credentials should be sent to a custom test server. Consequently, a URL ...[truncated 1863 chars]- Remediation
View remediation
str: parsed = urlparse(value) if parsed.scheme != "https": raise OuraError("The API base URL must use HTTPS.") if parsed.hostname not in ALLOWED_API_HOSTS: raise OuraError("The API host is not permitted.") if parsed.username or parsed.password: raise OuraError("URL user information is not permitted.") return value ``` 2. Apply validation after resolving the command-line argument and environment variable, before constructing `OuraClient`. 3. Prefer removing `--base-url` and `OURA_BASE_URL` from production usage if custom endpoints are not essential to the Skill's declared functionality. 4. If custom endpoints are required for testing: - Require a conspicuous development-only flag. - Do not use a production Oura token. - Require a separately named test credential. - Display the destination and request explicit confirmation when interactive. - Reject plaintext HTTP except for tightly controlled loopback-only testing. 5. Document the exact hosts that receive credentials and the OAuth scopes required by each command. 6. Recommend token revocation and replacement if an untrusted base URL may already have been used. ]]>
