Database query may not be scoped by shop
Detects database queries in authenticated routes that don't reference the shop domain or session.
| Detail | Value |
|---|---|
| Check ID | MISSING_TENANT_ISOLATION |
| Severity | High |
| How it runs | Agent review |
Anchor to Vulnerable exampleVulnerable example
app/routes/app.orders.$id.tsx
import type { LoaderFunctionArgs } from "react-router";
import { authenticate } from "../shopify.server";
import prisma from "../db.server";
export const loader = async ({ request, params }: LoaderFunctionArgs) => {
await authenticate.admin(request);
// Authenticated, but the row is selected by id alone: any
// installed shop can read any other shop's order by guessing or
// enumerating the id.
return {
order: await prisma.order.findUnique({ where: { id: params.id } }),
};
};
Anchor to How to fixHow to fix
Add the authenticated shop to the query's where clause.
For more detail, see Session tokens.
app/routes/app.orders.$id.tsx
import type { LoaderFunctionArgs } from "react-router";
import { authenticate } from "../shopify.server";
import prisma from "../db.server";
export const loader = async ({ request, params }: LoaderFunctionArgs) => {
const { session } = await authenticate.admin(request);
// Every tenant-owned read carries the shop in its where clause.
const order = await prisma.order.findFirst({
where: { id: params.id, shop: session.shop },
});
if (!order) throw new Response("Not found", { status: 404 });
return { order };
};
shopify app security check, the command that runs this check- All app security checks
Was this page helpful?