{"record":{"id":"a73bd3c59b3a3a0a","repo":"Budibase/budibase","slug":"redirect-to-a-different-origin-is-not-permitted","errorCode":null,"errorMessage":"Redirect to a different origin is not permitted.","messagePattern":"Redirect to a different origin is not permitted\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/backend-core/src/utils/outboundFetch.ts","lineNumber":245,"sourceCode":"    if (redirects === MAX_REDIRECTS) {\n      break\n    }\n\n    const location = response.headers.get(\"location\")\n    if (!location) {\n      if (returnRedirectWithoutLocation) {\n        return response\n      }\n      throw new Error(\"Maximum redirect reached.\")\n    }\n\n    const redirectUrl = parseUrl(\n      new URL(location, nextUrl).toString()\n    ).toString()\n    nextRequest = nextRequestForRedirect(nextRequest, response.status)\n    if (shouldStripSensitiveHeadersForRedirect(nextUrl, redirectUrl)) {\n      if (rejectCrossOriginRedirects) {\n        throw new Error(\"Redirect to a different origin is not permitted.\")\n      }\n      nextRequest = stripSensitiveHeadersForRedirect(nextRequest)\n    }\n    nextUrl = redirectUrl\n  }\n\n  throw new Error(\"Maximum redirect reached.\")\n}\n","sourceCodeStart":227,"sourceCodeEnd":254,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/backend-core/src/utils/outboundFetch.ts#L227-L254","documentation":"When a redirect crosses origins (current URL origin differs from the redirect target's origin) and the caller set rejectCrossOriginRedirects: true, the library throws instead of following. This protects credentials and prevents redirects being used to smuggle requests to unintended hosts.","triggerScenarios":"fetchWithBlacklist called with { rejectCrossOriginRedirects: true } and the server redirects to a different origin — e.g. api.example.com → auth.example.com/login, or http → https on a different host.","commonSituations":"SSO/login flows redirecting to another domain; CDN or apex↔www redirects (example.com → www.example.com); environment config pointing at a host that 301s to its canonical domain.","solutions":["Use the final destination URL directly so no cross-origin redirect occurs.","Drop rejectCrossOriginRedirects (leave default false) if the cross-origin hop is trusted — sensitive headers will then be stripped automatically.","If authentication is involved, perform the auth flow against the target origin rather than following redirects with credentials."],"exampleFix":"// before\nawait fetchWithBlacklist(\"https://example.com/data\", req, { rejectCrossOriginRedirects: true })\n// after (server 301s to www.example.com)\nawait fetchWithBlacklist(\"https://www.example.com/data\", req, { rejectCrossOriginRedirects: true })","handlingStrategy":"validation","validationCode":"// Resolve redirects manually and assert same-origin before the guarded call\nlet current = url\nfor (let i = 0; i < 5; i++) {\n  const res = await fetchWithBlacklist(current, { followRedirects: false })\n  if (![301,302,303,307,308].includes(res.status)) break\n  const loc = res.headers.get(\"location\")\n  if (!loc) break\n  const next = new URL(loc, current)\n  if (next.origin !== new URL(current).origin) {\n    throw new Error(`Cross-origin redirect to ${next.origin} not allowed`)\n  }\n  current = next.toString()\n}","typeGuard":null,"tryCatchPattern":"try {\n  return await fetchWithBlacklist(url, req, { rejectCrossOriginRedirects: true })\n} catch (err) {\n  if (err instanceof Error && err.message.includes(\"different origin\")) {\n    throw new Error(\"Endpoint redirects off-origin; use its final URL directly\")\n  }\n  throw err\n}","preventionTips":["Pin integrations to the canonical origin (follow the redirect once and store the final host).","Never send Authorization/Cookie headers to endpoints known to cross-origin redirect.","Treat cross-origin redirects on auth flows as a security smell."],"tags":["http","redirect","security","cross-origin"],"backgroundTag":"cross-origin-redirect-blocked","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}