Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 20s
Build & Deploy / 🧪 QA (push) Failing after 34s
Build & Deploy / 🏗️ Build (push) Has started running
Build & Deploy / 🚀 Deploy (push) Has been cancelled
Build & Deploy / 🧪 Smoke Test (push) Has been cancelled
Build & Deploy / ⚡ Lighthouse (push) Has been cancelled
Build & Deploy / 🔔 Notify (push) Has been cancelled
1 line
2.5 KiB
Plaintext
1 line
2.5 KiB
Plaintext
{"version":3,"sources":["../../src/utilities/getSafeRedirect.ts"],"sourcesContent":["export const getSafeRedirect = ({\n allowAbsoluteUrls = false,\n fallbackTo = '/',\n redirectTo,\n}: {\n allowAbsoluteUrls?: boolean\n fallbackTo?: string\n redirectTo: string | string[]\n}): string => {\n if (typeof redirectTo !== 'string') {\n return fallbackTo\n }\n\n // Normalize and decode the path\n let redirectPath: string\n try {\n redirectPath = decodeURIComponent(redirectTo.trim())\n } catch {\n return fallbackTo // invalid encoding\n }\n\n const isSafeRedirect =\n // Must start with a single forward slash (e.g., \"/admin\")\n redirectPath.startsWith('/') &&\n // Prevent protocol-relative URLs (e.g., \"//example.com\")\n !redirectPath.startsWith('//') &&\n // Prevent encoded slashes that could resolve to protocol-relative\n !redirectPath.startsWith('/%2F') &&\n // Prevent backslash-based escape attempts (e.g., \"/\\\\/example.com\", \"/\\\\\\\\example.com\", \"/\\\\example.com\")\n !redirectPath.startsWith('/\\\\/') &&\n !redirectPath.startsWith('/\\\\\\\\') &&\n !redirectPath.startsWith('/\\\\') &&\n // Prevent javascript-based schemes (e.g., \"/javascript:alert(1)\")\n !redirectPath.toLowerCase().startsWith('/javascript:') &&\n // Prevent attempts to redirect to full URLs using \"/http:\" or \"/https:\"\n !redirectPath.toLowerCase().startsWith('/http')\n\n const isAbsoluteSafeRedirect =\n allowAbsoluteUrls &&\n // Must be a valid absolute URL with http or https\n /^https?:\\/\\/\\S+$/i.test(redirectPath)\n\n return isSafeRedirect || isAbsoluteSafeRedirect ? redirectPath : fallbackTo\n}\n"],"names":["getSafeRedirect","allowAbsoluteUrls","fallbackTo","redirectTo","redirectPath","decodeURIComponent","trim","isSafeRedirect","startsWith","toLowerCase","isAbsoluteSafeRedirect","test"],"mappings":"AAAA,OAAO,MAAMA,kBAAkB,CAAC,EAC9BC,oBAAoB,KAAK,EACzBC,aAAa,GAAG,EAChBC,UAAU,EAKX;IACC,IAAI,OAAOA,eAAe,UAAU;QAClC,OAAOD;IACT;IAEA,gCAAgC;IAChC,IAAIE;IACJ,IAAI;QACFA,eAAeC,mBAAmBF,WAAWG,IAAI;IACnD,EAAE,OAAM;QACN,OAAOJ,WAAW,mBAAmB;;IACvC;IAEA,MAAMK,iBACJ,0DAA0D;IAC1DH,aAAaI,UAAU,CAAC,QACxB,yDAAyD;IACzD,CAACJ,aAAaI,UAAU,CAAC,SACzB,kEAAkE;IAClE,CAACJ,aAAaI,UAAU,CAAC,WACzB,0GAA0G;IAC1G,CAACJ,aAAaI,UAAU,CAAC,WACzB,CAACJ,aAAaI,UAAU,CAAC,YACzB,CAACJ,aAAaI,UAAU,CAAC,UACzB,kEAAkE;IAClE,CAACJ,aAAaK,WAAW,GAAGD,UAAU,CAAC,mBACvC,wEAAwE;IACxE,CAACJ,aAAaK,WAAW,GAAGD,UAAU,CAAC;IAEzC,MAAME,yBACJT,qBACA,kDAAkD;IAClD,oBAAoBU,IAAI,CAACP;IAE3B,OAAOG,kBAAkBG,yBAAyBN,eAAeF;AACnE,EAAC"} |