@@ -10,6 +10,7 @@ import { shouldHydrateRouteLoader } from "../dom/ssr/routes";
1010import type { RSCPayload } from "./server.rsc" ;
1111import { createRSCRouteModules } from "./route-modules" ;
1212import { isRouteErrorResponse , type DataRouteObject } from "../router/utils" ;
13+ import { hasInvalidProtocol } from "../router/router" ;
1314import {
1415 decodeRedirectErrorDigest ,
1516 decodeRouteErrorResponseDigest ,
@@ -202,6 +203,10 @@ export async function routeRSCServerRequest({
202203 serverResponse . status === SINGLE_FETCH_REDIRECT_STATUS &&
203204 payload . type === "redirect"
204205 ) {
206+ if ( hasInvalidProtocol ( payload . location ) ) {
207+ throw new Error ( "Invalid redirect location" ) ;
208+ }
209+
205210 const headers = new Headers ( serverResponse . headers ) ;
206211 headers . delete ( "Content-Encoding" ) ;
207212 headers . delete ( "Content-Length" ) ;
@@ -255,6 +260,10 @@ export async function routeRSCServerRequest({
255260 headers . set ( "Content-Type" , "text/html; charset=utf-8" ) ;
256261
257262 if ( renderRedirect ) {
263+ if ( hasInvalidProtocol ( renderRedirect . location ) ) {
264+ throw new Error ( "Invalid redirect location" ) ;
265+ }
266+
258267 headers . set ( "Location" , renderRedirect . location ) ;
259268 return new Response ( html , {
260269 status : renderRedirect . status ,
@@ -265,6 +274,10 @@ export async function routeRSCServerRequest({
265274 const redirectTransform = new TransformStream ( {
266275 flush ( controller ) {
267276 if ( renderRedirect ) {
277+ if ( hasInvalidProtocol ( renderRedirect . location ) ) {
278+ return ;
279+ }
280+
268281 controller . enqueue (
269282 new TextEncoder ( ) . encode (
270283 `<meta http-equiv="refresh" content="0;url=${ escapeHtml ( renderRedirect . location ) } "/>` ,
@@ -300,6 +313,10 @@ export async function routeRSCServerRequest({
300313 }
301314
302315 if ( renderRedirect ) {
316+ if ( hasInvalidProtocol ( renderRedirect . location ) ) {
317+ throw new Error ( "Invalid redirect location" ) ;
318+ }
319+
303320 return new Response ( `Redirect: ${ renderRedirect . location } ` , {
304321 status : renderRedirect . status ,
305322 headers : {
@@ -388,6 +405,10 @@ export async function routeRSCServerRequest({
388405 headers . set ( "Content-Type" , "text/html; charset=utf-8" ) ;
389406
390407 if ( retryRedirect ) {
408+ if ( hasInvalidProtocol ( retryRedirect . location ) ) {
409+ throw new Error ( "Invalid redirect location" ) ;
410+ }
411+
391412 headers . set ( "Location" , retryRedirect . location ) ;
392413 return new Response ( html , {
393414 status : retryRedirect . status ,
@@ -398,6 +419,10 @@ export async function routeRSCServerRequest({
398419 const retryRedirectTransform = new TransformStream ( {
399420 flush ( controller ) {
400421 if ( retryRedirect ) {
422+ if ( hasInvalidProtocol ( retryRedirect . location ) ) {
423+ return ;
424+ }
425+
401426 controller . enqueue (
402427 new TextEncoder ( ) . encode (
403428 `<meta http-equiv="refresh" content="0;url=${ escapeHtml ( retryRedirect . location ) } "/>` ,
@@ -495,6 +520,10 @@ export function RSCStaticRouter({ getPayload }: RSCStaticRouterProps) {
495520 const payload = useSafe ( decoded ) ;
496521
497522 if ( payload . type === "redirect" ) {
523+ if ( hasInvalidProtocol ( payload . location ) ) {
524+ throw new Error ( "Invalid redirect location" ) ;
525+ }
526+
498527 throw new Response ( null , {
499528 status : payload . status ,
500529 headers : {
0 commit comments