T09 · Insecure Skill Coding Practices
- Location
templates/buddy_oauth_callback_local.py:42- Finding
OAuth credentials may be transmitted to an arbitrary or plaintext token endpoint
- Content
View full analysis
dict: """Authorization-code exchange.""" if not TOKEN_ENDPOINT: raise RuntimeError( "WB_TOKEN_ENDPOINT is not configured" ) form = { "grant_type": "authorization_code", "code": code, "redirect_uri": REDIRECT_URI, "client_id": CLIENT_ID, "client_secret": CLIENT_SECRET, } req = urllib.request.Request( TOKEN_ENDPOINT, data=urllib.parse.urlencode(form).encode("utf-8"), headers={ "Content-Type": "application/x-www-form-urlencoded", "Accept": "application/json", }, method="POST", ) with urllib.request.urlopen(req, timeout=15) as resp: return json.loads(resp.read().decode("utf-8")) ``` Serverless callback implementation: ```python TOKEN_ENDPOINT = os.environ.get("WB_TOKEN_ENDPOINT", "") def exchange_code(code: str) -> dict: """Exchange an authorization code for a token.""" if not TOKEN_ENDPOINT: raise RuntimeError( "WB_TOKEN_ENDPOINT is not configured" ) form = { "grant_type": "authorization_code", "code": code, "redirect_uri": REDIRECT_URI, "client_id": CLIENT_ID, "client_secret": CLIENT_SECRET, } req = urllib.request.Request( TOKEN_ENDPOINT, data=urllib.parse.urlencode(form).encode("utf-8"), headers={ "Content-Type": "application/x-www-form-urlencoded", "Accept": "application/json", }, method="POST", ) with urllib.request. ...[truncated 2336 chars]- Remediation
View remediation
str: parsed = urlsplit(value) if parsed.scheme != "https": raise RuntimeError("The OAuth token endpoint must use HTTPS") if parsed.hostname not in ALLOWED_TOKEN_HOSTS: raise RuntimeError("The OAuth token endpoint host is not approved") if parsed.username or parsed.password: raise RuntimeError("Embedded URL credentials are prohibited") if parsed.fragment: raise RuntimeError("Token endpoint fragments are prohibited") if parsed.port not in (None, 443): raise RuntimeError("Unexpected token endpoint port") return value ``` 2. Prefer a fixed endpoint supplied by trusted application configuration rather than a freely configurable URL. 3. Validate the endpoint during application startup so an unsafe deployment fails before accepting callbacks. 4. Use TLS certificate validation and do not disable Python's default certificate checks. 5. Prevent or tightly control redirects during token exchange. If redirects are required, revalidate every destination before transmitting sensitive data. 6. Never include authorization codes, secrets, or full tokens in logs or error responses. 7. Add tests that reject HTTP, loopback, link-local, private-network, credential-bearing, and unapproved-host URLs. ]]>
