{"record":{"id":"aceceeed408abe72","repo":"decolua/9router","slug":"xai-discovery-field-host-host-is-not-on-x-a","errorCode":null,"errorMessage":"`xai discovery ${field} host ${host} is not on x.ai`","messagePattern":"`xai discovery (.+?) host (.+?) is not on x\\.ai`","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"src/lib/oauth/providerHelpers.js","lineNumber":13,"sourceCode":"const BASE64_BLOCK_SIZE = 4;\n\nfunction validateXaiOAuthEndpoint(rawUrl, field) {\n  const value = String(rawUrl || \"\").trim();\n  if (!value) throw new Error(`xai discovery ${field} is empty`);\n  let parsed;\n  try { parsed = new URL(value); } catch (err) {\n    throw new Error(`xai discovery ${field} is invalid: ${err.message}`);\n  }\n  if (parsed.protocol !== \"https:\") throw new Error(`xai discovery ${field} must use https: ${value}`);\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  return value;\n}\n\nfunction decodeXaiIdTokenEmail(idToken) {\n  if (!idToken || typeof idToken !== \"string\") return undefined;\n  const parts = idToken.split(\".\");\n  if (parts.length !== 3) return undefined;\n  try {\n    const base64 = parts[1].replace(/-/g, \"+\").replace(/_/g, \"/\");\n    const padding = (BASE64_BLOCK_SIZE - (base64.length % BASE64_BLOCK_SIZE)) % BASE64_BLOCK_SIZE;\n    const json = Buffer.from(base64 + \"=\".repeat(padding), \"base64\").toString(\"utf8\");\n    const payload = JSON.parse(json);\n    return payload.email || payload.preferred_username || payload.sub || undefined;\n  } catch {\n    return undefined;\n  }\n}","sourceCodeStart":1,"sourceCodeEnd":31,"githubUrl":"https://github.com/decolua/9router/blob/90b52e06ffd666b7929554211474d01588f6b1f8/src/lib/oauth/providerHelpers.js#L1-L31","documentation":"validateXaiOAuthEndpoint allowlists endpoint hosts: the hostname must be exactly 'x.ai' or a subdomain ending in '.x.ai'. Any other host (including lookalikes like xai.com, evil-x.ai, or an IP address) is rejected with this error naming the field and offending host. This blocks phishing/token-exfiltration via a compromised discovery document; discoverXaiEndpoints catches it and falls back to static x.ai endpoints.","triggerScenarios":"Discovery response advertises authorization_endpoint/token_endpoint on a foreign host, or a developer points discoveryUrl at a mirror whose endpoints live on another domain.","commonSituations":"Third-party xAI-compatible proxies, DNS hijacking or captive portals rewriting hostnames, DNS-based content filters, or security tests verifying the allowlist.","solutions":["Use the official discovery URL so endpoints resolve to x.ai hosts; drop any custom discoveryUrl override.","Accept the built-in static fallback endpoints in discoverXaiEndpoints.","If you legitimately need a different host (e.g. corporate proxy), you must fork/extend the allowlist rather than passing the URL through.","Investigate DNS/proxy tampering if the host changed unexpectedly."],"exampleFix":"// before\nvalidateXaiOAuthEndpoint('https://auth.xai-mirror.example.com/token', 'token_endpoint'); // throws: host is not on x.ai\n// after\nvalidateXaiOAuthEndpoint('https://auth.x.ai/token', 'token_endpoint');","handlingStrategy":"validation","validationCode":"function isXaiHost(v) {\n  try {\n    const h = new URL(String(v).trim()).hostname.toLowerCase();\n    return h === 'x.ai' || h.endsWith('.x.ai');\n  } catch { return false; }\n}\n// if (!isXaiHost(data.token_endpoint)) use static x.ai endpoints","typeGuard":"function isXaiEndpoint(v) {\n  if (typeof v !== 'string') return false;\n  try {\n    const u = new URL(v.trim());\n    if (u.protocol !== 'https:') return false;\n    const h = u.hostname.toLowerCase();\n    return h === 'x.ai' || h.endsWith('.x.ai');\n  } catch { return false; }\n}","tryCatchPattern":"try {\n  const url = validateXaiOAuthEndpoint(raw, 'authorization_endpoint');\n  // use url\n} catch (err) {\n  if (/is not on x\\.ai/.test(err.message)) {\n    // suspected tampering/mirror — use official static endpoints and alert\n    console.error('xAI discovery host rejected:', err.message);\n    return XAI_CONFIG.authorizeUrl;\n  }\n  throw err;\n}","preventionTips":["Never point discoveryUrl at third-party xAI-compatible mirrors in production.","Monitor DNS/proxy health; unexpected hostnames usually indicate hijacking.","Keep the host allowlist intact — do not 'fix' this error by loosening it to an untrusted host.","Pin the static x.ai endpoints so any discovery failure degrades safely."],"tags":["oauth","xai","security","allowlist","url-validation"],"backgroundTag":"oauth-endpoint-host-allowlist","analyzedSha":"90b52e06ffd666b7929554211474d01588f6b1f8","analyzedAt":"2026-08-30T21:05:45.952Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}