Skip to main content

Open redirect in auth callback

Detects redirect targets taken from request parameters without validation.

DetailValue
Check IDOPEN_REDIRECT
SeverityMedium
How it runsAgent review

app/routes/auth.callback.tsx

import { redirect } from "react-router";
import type { LoaderFunctionArgs } from "react-router";

import { authenticate } from "../shopify.server";

export const loader = async ({ request }: LoaderFunctionArgs) => {
await authenticate.admin(request);

const returnTo = new URL(request.url).searchParams.get("return_to");

// The destination is whatever the caller put in the URL, so the
// app will bounce a freshly authenticated merchant to an
// attacker's page.
return redirect(returnTo ?? "/app");
};

Validate the redirect URL against an allowlist of permitted domains.

For more detail, see Authentication and authorization.

app/routes/auth.callback.tsx

import { redirect } from "react-router";
import type { LoaderFunctionArgs } from "react-router";

import { authenticate } from "../shopify.server";

const ALLOWED_PATHS = ["/app", "/app/settings", "/app/orders"];

export const loader = async ({ request }: LoaderFunctionArgs) => {
await authenticate.admin(request);

const returnTo = new URL(request.url).searchParams.get("return_to");

// Allowlist the destination. Accepting only known in-app paths
// also rules out protocol-relative targets such as
// //evil.example.
const destination = ALLOWED_PATHS.includes(returnTo ?? "")
? returnTo!
: "/app";

return redirect(destination);
};


Was this page helpful?