{"version":3,"sources":["../../../../src/server/lib/router-utils/block-cross-site.ts"],"sourcesContent":["import type { Duplex } from 'stream'\nimport type { IncomingMessage, ServerResponse } from 'node:http'\nimport { parseUrl } from '../../../lib/url'\nimport { warnOnce } from '../../../build/output/log'\nimport { isCsrfOriginAllowed } from '../../app-render/csrf-protection'\n\nfunction warnOrBlockRequest(\n res: ServerResponse | Duplex,\n origin: string | undefined,\n mode: 'warn' | 'block'\n): boolean {\n const originString = origin ? `from ${origin}` : ''\n if (mode === 'warn') {\n warnOnce(\n `Cross origin request detected ${originString} to /_next/* resource. In a future major version of Next.js, you will need to explicitly configure \"allowedDevOrigins\" in next.config to allow this.\\nRead more: https://nextjs.org/docs/app/api-reference/config/next-config-js/allowedDevOrigins`\n )\n\n return false\n }\n\n warnOnce(\n `Blocked cross-origin request ${originString} to /_next/* resource. To allow this, configure \"allowedDevOrigins\" in next.config\\nRead more: https://nextjs.org/docs/app/api-reference/config/next-config-js/allowedDevOrigins`\n )\n\n if ('statusCode' in res) {\n res.statusCode = 403\n }\n\n res.end('Unauthorized')\n\n return true\n}\n\nfunction isInternalDevEndpoint(req: IncomingMessage): boolean {\n if (!req.url) return false\n\n try {\n // TODO: We should standardize on a single prefix for this\n const isMiddlewareRequest = req.url.includes('/__nextjs')\n const isInternalAsset = req.url.includes('/_next')\n // Static media requests are excluded, as they might be loaded via CSS and would fail\n // CORS checks.\n const isIgnoredRequest =\n req.url.includes('/_next/image') ||\n req.url.includes('/_next/static/media')\n\n return !isIgnoredRequest && (isInternalAsset || isMiddlewareRequest)\n } catch (err) {\n return false\n }\n}\n\nexport const blockCrossSite = (\n req: IncomingMessage,\n res: ServerResponse | Duplex,\n allowedDevOrigins: string[] | undefined,\n hostname: string | undefined\n): boolean => {\n // in the future, these will be blocked by default when allowed origins aren't configured.\n // for now, we warn when allowed origins aren't configured\n const mode = typeof allowedDevOrigins === 'undefined' ? 'warn' : 'block'\n\n const allowedOrigins = [\n '*.localhost',\n 'localhost',\n ...(allowedDevOrigins || []),\n ]\n if (hostname) {\n allowedOrigins.push(hostname)\n }\n\n // only process internal URLs/middleware\n if (!isInternalDevEndpoint(req)) {\n return false\n }\n // block non-cors request from cross-site e.g. script tag on\n // different host\n if (\n req.headers['sec-fetch-mode'] === 'no-cors' &&\n req.headers['sec-fetch-site'] === 'cross-site'\n ) {\n return warnOrBlockRequest(res, undefined, mode)\n }\n\n // ensure websocket requests from allowed origin\n const rawOrigin = req.headers['origin']\n\n if (rawOrigin) {\n const parsedOrigin = parseUrl(rawOrigin)\n\n if (parsedOrigin) {\n const originLowerCase = parsedOrigin.hostname.toLowerCase()\n\n if (!isCsrfOriginAllowed(originLowerCase, allowedOrigins)) {\n return warnOrBlockRequest(res, originLowerCase, mode)\n }\n }\n }\n\n return false\n}\n"],"names":["blockCrossSite","warnOrBlockRequest","res","origin","mode","originString","warnOnce","statusCode","end","isInternalDevEndpoint","req","url","isMiddlewareRequest","includes","isInternalAsset","isIgnoredRequest","err","allowedDevOrigins","hostname","allowedOrigins","push","headers","undefined","rawOrigin","parsedOrigin","parseUrl","originLowerCase","toLowerCase","isCsrfOriginAllowed"],"mappings":";;;;+BAoDaA;;;eAAAA;;;qBAlDY;qBACA;gCACW;AAEpC,SAASC,mBACPC,GAA4B,EAC5BC,MAA0B,EAC1BC,IAAsB;IAEtB,MAAMC,eAAeF,SAAS,CAAC,KAAK,EAAEA,QAAQ,GAAG;IACjD,IAAIC,SAAS,QAAQ;QACnBE,IAAAA,aAAQ,EACN,CAAC,8BAA8B,EAAED,aAAa,kPAAkP,CAAC;QAGnS,OAAO;IACT;IAEAC,IAAAA,aAAQ,EACN,CAAC,6BAA6B,EAAED,aAAa,gLAAgL,CAAC;IAGhO,IAAI,gBAAgBH,KAAK;QACvBA,IAAIK,UAAU,GAAG;IACnB;IAEAL,IAAIM,GAAG,CAAC;IAER,OAAO;AACT;AAEA,SAASC,sBAAsBC,GAAoB;IACjD,IAAI,CAACA,IAAIC,GAAG,EAAE,OAAO;IAErB,IAAI;QACF,0DAA0D;QAC1D,MAAMC,sBAAsBF,IAAIC,GAAG,CAACE,QAAQ,CAAC;QAC7C,MAAMC,kBAAkBJ,IAAIC,GAAG,CAACE,QAAQ,CAAC;QACzC,qFAAqF;QACrF,eAAe;QACf,MAAME,mBACJL,IAAIC,GAAG,CAACE,QAAQ,CAAC,mBACjBH,IAAIC,GAAG,CAACE,QAAQ,CAAC;QAEnB,OAAO,CAACE,oBAAqBD,CAAAA,mBAAmBF,mBAAkB;IACpE,EAAE,OAAOI,KAAK;QACZ,OAAO;IACT;AACF;AAEO,MAAMhB,iBAAiB,CAC5BU,KACAR,KACAe,mBACAC;IAEA,0FAA0F;IAC1F,0DAA0D;IAC1D,MAAMd,OAAO,OAAOa,sBAAsB,cAAc,SAAS;IAEjE,MAAME,iBAAiB;QACrB;QACA;WACIF,qBAAqB,EAAE;KAC5B;IACD,IAAIC,UAAU;QACZC,eAAeC,IAAI,CAACF;IACtB;IAEA,wCAAwC;IACxC,IAAI,CAACT,sBAAsBC,MAAM;QAC/B,OAAO;IACT;IACA,4DAA4D;IAC5D,iBAAiB;IACjB,IACEA,IAAIW,OAAO,CAAC,iBAAiB,KAAK,aAClCX,IAAIW,OAAO,CAAC,iBAAiB,KAAK,cAClC;QACA,OAAOpB,mBAAmBC,KAAKoB,WAAWlB;IAC5C;IAEA,gDAAgD;IAChD,MAAMmB,YAAYb,IAAIW,OAAO,CAAC,SAAS;IAEvC,IAAIE,WAAW;QACb,MAAMC,eAAeC,IAAAA,aAAQ,EAACF;QAE9B,IAAIC,cAAc;YAChB,MAAME,kBAAkBF,aAAaN,QAAQ,CAACS,WAAW;YAEzD,IAAI,CAACC,IAAAA,mCAAmB,EAACF,iBAAiBP,iBAAiB;gBACzD,OAAOlB,mBAAmBC,KAAKwB,iBAAiBtB;YAClD;QACF;IACF;IAEA,OAAO;AACT","ignoreList":[0]}