T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/idp_evidence.py:298
- Finding
- Okta API Token Can Be Transmitted to an Arbitrary HTTPS Host<![CDATA[ ## Vulnerability Details **File Location**: `scripts/idp_evidence.py:161-165`, `scripts/idp_evidence.py:298-305`; the resulting configuration is consumed by all Okta check modules **Vulnerability Type**: Insufficient destination validation before transmitting credentials **Risk Level**: High ### Vulnerable Code ```python def _build_okta_config(): """Build the Okta client configuration dict.""" return { "orgUrl": os.environ["OKTA_ORG_URL"], "token": os.environ["OKTA_API_TOKEN"], } ``` ```python org_url = os.environ["OKTA_ORG_URL"].rstrip("/") if not org_url.startswith("https://"): print(json.dumps({"status": "error", "message": "OKTA_ORG_URL must use HTTPS"})) sys.exit(1) token = os.environ["OKTA_API_TOKEN"] headers = {"Authorization": f"SSWS {token}", "Accept": "application/json"} # Test user endpoint resp = requests.get(f"{org_url}/api/v1/users?limit=1", headers=headers, timeout=10) ``` ### Technical Analysis The application obtains both the Okta organization URL and API token from environment variables. It only verifies that the URL string begins with `https://`; it does not parse the URL or verify that the hostname is the expected Okta tenant. Consequently, any HTTPS server can be configured as `OKTA_ORG_URL`. The connection test directly sends the SSWS token in the `Authorization` header to that server. The same unrestricted `orgUrl` and token are passed to the Okta SDK for normal checks. HTTPS protects the connection in transit but does not establish that the destination is authorized to receive the credential. Prefix validation also fails to reject unexpected ports, embedded URL credentials, misleading hostnames, or attacker-controlled non-Okta domains. ### Attack Path 1. An attacker gains the ability to modify `OKTA_ORG_URL` in the Skill's environment or deployment configuration. 2. The legitimate `OKTA_API_TOKEN` remains configured. 3. The attacker sets `OKTA_ORG_URL` to an attacker-controlled HTTPS ...[truncated 953 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Parse the URL with `urllib.parse.urlsplit` rather than using string-prefix validation. 2. Require: - Scheme exactly equal to `https` - No embedded username or password - No fragment or unexpected query - An explicitly approved port - A hostname matching the configured tenant allowlist 3. Require administrators to configure the expected tenant hostname separately and compare it exactly before attaching credentials. 4. Consider restricting standard Okta deployments to documented Okta domain suffixes, while supporting custom domains only through an explicit allowlist. 5. Never follow redirects to a different origin while retaining the `Authorization` header. 6. Prefer a scoped OAuth service application over an inherited-permission SSWS token. 7. Add automated tests covering attacker-controlled domains, deceptive subdomains, userinfo URLs, alternate ports, redirects, and malformed URLs. ]]>
