Skip to main content

App proxy Liquid injection risk

Detects app proxy endpoints that interpolate request parameters into active Liquid or HTML responses.

DetailValue
Check IDAPP_PROXY_LIQUID_INJECTION
SeverityHigh
How it runsDeterministic scan and agent review

app/routes/proxy.welcome.tsx

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

export const loader = async ({ request }: LoaderFunctionArgs) => {
const shop = new URL(request.url).searchParams.get("shop");

// Request input interpolated into a Liquid response. The
// storefront renders the body as Liquid, so injected tags
// such as {{ customer.email }} run too.
return new Response(`<div>Welcome, ${shop}</div>`, {
headers: { "Content-Type": "application/liquid" },
});
};

Don't interpolate user input into application/liquid responses. Use application/json or escape all input.

For more detail, see App proxies.

app/routes/proxy.welcome.tsx

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

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

export const loader = async ({ request }: LoaderFunctionArgs) => {
// The verified session carries the shop, and JSON is not an
// active content type, so nothing in the body is evaluated.
const { session } = await authenticate.public.appProxy(request);

return new Response(JSON.stringify({ shop: session?.shop }), {
headers: { "Content-Type": "application/json" },
});
};


Was this page helpful?