{"record":{"id":"27f0840b2b8484a1","repo":"decolua/9router","slug":"xai-discovery-field-must-use-https-value-27f084","errorCode":null,"errorMessage":"xai discovery ${field} must use https: ${value}","messagePattern":"xai discovery (.+?) must use https: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/lib/oauth/services/xai.js","lineNumber":38,"sourceCode":" */\n\nconst BASE64_BLOCK_SIZE = 4;\n\nlet cachedDiscovery = null;\n\nexport function validateOAuthEndpoint(rawUrl, field) {\n  const value = String(rawUrl || \"\").trim();\n  if (!value) throw new Error(`xai discovery ${field} is empty`);\n\n  let parsed;\n  try {\n    parsed = new URL(value);\n  } catch (err) {\n    throw new Error(`xai discovery ${field} is invalid: ${err.message}`);\n  }\n\n  if (parsed.protocol !== \"https:\") {\n    throw new Error(`xai discovery ${field} must use https: ${value}`);\n  }\n\n  const host = parsed.hostname.toLowerCase().trim();\n  if (host !== \"x.ai\" && !host.endsWith(\".x.ai\")) {\n    throw new Error(`xai discovery ${field} host ${host} is not on x.ai`);\n  }\n\n  return value;\n}\n\n/**\n * Discover authorization + token endpoints. Cached process-wide.\n */\nexport async function discoverEndpoints() {\n  if (cachedDiscovery) return cachedDiscovery;\n\n  try {\n    const res = await fetch(XAI_CONFIG.discoveryUrl, {","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/decolua/9router/blob/90b52e06ffd666b7929554211474d01588f6b1f8/src/lib/oauth/services/xai.js#L20-L56","documentation":"validateOAuthEndpoint enforces that every xAI discovery endpoint uses the https: protocol; http:// values are rejected to prevent token/authorization leakage over plaintext. The offending value is included in the message.","triggerScenarios":"A discovery field or manual override points at http://x.ai/... — e.g. local development URLs, reverse proxies terminating TLS upstream, or an insecure entry in a spoofed/mis-scoped discovery document.","commonSituations":"Developers pointing endpoints at a local http mock during testing; self-hosted proxies exposing xAI endpoints over http on an internal network.","solutions":["Change the endpoint URL scheme to https://.","If you need local testing, put the mock behind a locally trusted TLS proxy (e.g. mkcert) — http is not accepted by design.","Verify the discovery document you consumed actually came from x.ai, since a non-https endpoint there indicates tampering."],"exampleFix":"// before\nXAI_AUTH_URL=http://x.ai/oauth/authorize\n// after\nXAI_AUTH_URL=https://x.ai/oauth/authorize","handlingStrategy":"validation","validationCode":"if (!/^https:\\/\\//i.test(cfg.authorizationUrl)) {\n  throw new Error('xAI endpoints must use https://');\n}","typeGuard":"function isHttpsUrl(u) {\n  try { return new URL(String(u).trim()).protocol === 'https:'; } catch { return false; }\n}","tryCatchPattern":null,"preventionTips":["Never configure http:// endpoints for production OAuth flows.","For local testing use a TLS-enabled mock (mkcert + local https server), not plain http.","Treat any http endpoint appearing in a discovery document as tampering."],"tags":["oauth","xai","security","https","url"],"backgroundTag":"oauth-endpoint-not-https","analyzedSha":"90b52e06ffd666b7929554211474d01588f6b1f8","analyzedAt":"2026-08-30T21:05:45.952Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}