Skip to content

Commit e9f3e4d

Browse files
authored
Merge pull request #27 from mcinquin/fix-csrf
fix(csrf): fix issue with CSRF
2 parents b61d0a5 + 662dd3f commit e9f3e4d

1 file changed

Lines changed: 23 additions & 2 deletions

File tree

‎src/lib/request-guard.ts‎

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,37 @@ import { getRequestTranslator } from "@/i18n/request";
33

44
const 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+
627
export 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

Comments
 (0)