@@ -3,16 +3,37 @@ import { getRequestTranslator } from "@/i18n/request";
33
44const SAFE_FETCH_SITES = new Set ( [ "same-origin" , "none" ] ) ;
55
6+ function trustProxyHeaders ( ) : boolean {
7+ return process . env . TRUST_PROXY ?. trim ( ) . toLowerCase ( ) === "true" ;
8+ }
9+
10+ function firstHeaderValue ( value : string | null ) : string | null {
11+ return value ?. split ( "," ) [ 0 ] ?. trim ( ) || null ;
12+ }
13+
14+ function getPublicOrigin ( request : NextRequest ) : string {
15+ const url = new URL ( request . url ) ;
16+ if ( ! trustProxyHeaders ( ) ) return url . origin ;
17+
18+ const proto = firstHeaderValue ( request . headers . get ( "x-forwarded-proto" ) ) ;
19+ const host =
20+ firstHeaderValue ( request . headers . get ( "x-forwarded-host" ) ) ??
21+ firstHeaderValue ( request . headers . get ( "host" ) ) ;
22+
23+ if ( ! proto || ! host ) return url . origin ;
24+ return `${ proto . toLowerCase ( ) } ://${ host . toLowerCase ( ) } ` ;
25+ }
26+
627export function rejectCrossSiteMutation (
728 request : NextRequest
829) : NextResponse | null {
930 const t = getRequestTranslator ( request ) ;
10- const requestOrigin = new URL ( request . url ) . origin ;
31+ const requestOrigin = getPublicOrigin ( request ) ;
1132 const origin = request . headers . get ( "origin" ) ;
1233
1334 if ( origin ) {
1435 try {
15- if ( new URL ( origin ) . origin !== requestOrigin ) {
36+ if ( new URL ( origin ) . origin . toLowerCase ( ) !== requestOrigin ) {
1637 return NextResponse . json (
1738 { error : t ( "errors.crossSiteRequest" ) } ,
1839 { status : 403 }
0 commit comments