T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/twitter_oauth_client.py:45
- Finding
- Arbitrary relay URL permits API key, post content, and media disclosure<![CDATA[ ## Vulnerability Details **File Location**: `scripts/twitter_oauth_client.py:45-57`, `scripts/twitter_oauth_client.py:78-104`, `scripts/twitter_oauth_client.py:168-184`, `scripts/twitter_oauth_client.py:373-406` **Vulnerability Type**: Unrestricted sensitive-data destination and plaintext transport **Risk Level**: High ### Vulnerable Code ```python def normalize_base_url(base_url: str) -> str: value = base_url.strip().rstrip("/") if not value: raise RelayConfigError("TWITTER_RELAY_BASE_URL is required.") parsed = urllib.parse.urlparse(value) if parsed.scheme not in {"http", "https"} or not parsed.netloc: raise RelayConfigError("TWITTER_RELAY_BASE_URL must be a valid http(s) URL.") return value def load_config(args: argparse.Namespace) -> Dict[str, Any]: base_url = normalize_base_url( get_env("TWITTER_RELAY_BASE_URL", DEFAULT_BASE_URL) ) aisa_api_key = getattr(args, "aisa_api_key", None) or get_env("AISA_API_KEY") timeout = getattr(args, "timeout", None) or int(get_env("TWITTER_RELAY_TIMEOUT", str(DEFAULT_TIMEOUT))) if not aisa_api_key: raise RelayConfigError("AISA_API_KEY is required.") return { "base_url": base_url, "aisa_api_key": aisa_api_key, "timeout": timeout, } ``` ```python def build_auth_headers(aisa_api_key: str, extra_headers: Optional[Dict[str, str]] = None) -> Dict[str, str]: headers = { "Authorization": f"Bearer {aisa_api_key}", "User-Agent": DEFAULT_CHROME_USER_AGENT, } if extra_headers: headers.update(extra_headers) return headers def send_json_request( url: str, payload: Dict[str, Any], timeout: int, aisa_api_key: str, ) -> Dict[str, Any]: request = urllib.request.Request( url, data=json.dumps(payload).encode("utf-8"), headers=build_auth_headers( aisa_api_key, {"Content-Type": "application/json", "Accept": "application ...[truncated 3781 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Remove `TWITTER_RELAY_BASE_URL` if custom relay deployments are not an explicitly supported requirement. 2. Otherwise, enforce an exact allowlist of trusted HTTPS origins, including the expected hostname and port: ```python TRUSTED_RELAY_ORIGINS = { ("https", "api.aisa.one", 443), } ``` 3. Reject: - Plaintext HTTP. - Embedded URL credentials. - Unexpected ports. - IP literals and unapproved subdomains. - URL fragments or malformed origins. 4. Ensure redirects cannot move a request to a different origin or downgrade it from HTTPS to HTTP. 5. Send the API key in only one authenticated channel. Remove the redundant `aisa_api_key` request-body field if the server supports bearer authentication. 6. Add tests confirming that malicious hosts, HTTP URLs, deceptive subdomains, embedded credentials, and cross-origin redirects are rejected. 7. Document every external destination and the exact data categories transmitted to it. ]]>
