---
title: Route handler lacks recognized auth verification
description: >-
  Detects a backend route that reads or writes shop data without verifying the
  request first.
source_url:
  html: >-
    https://shopify.dev/docs/apps/build/security/app-security-checks/unauthenticated-endpoint
  md: >-
    https://shopify.dev/docs/apps/build/security/app-security-checks/unauthenticated-endpoint.md
---

# Route handler lacks recognized auth verification

Detects a backend route that reads or writes shop data without verifying the request first.

The deterministic scan recognizes the app template's route-auth shape: an awaited `authenticate.*` call before the protected operation. A route that authenticates through `context.shopify.authenticate.admin` is handed to agent review rather than reported as missing authentication, because the scan can't tell from the spelling alone whether that call is awaited, genuine, and blocking.

| Detail | Value |
| - | - |
| Check ID | `UNAUTHENTICATED_ENDPOINT` |
| Severity | High |
| How it runs | Deterministic scan and agent review |
| Applies to | Apps with a backend |

***

## Vulnerable example

## app/routes/app.orders.tsx

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


import prisma from "../db.server";


// No authentication barrier: anyone who can reach the route
// reads the table.
export const loader = async ({ request }: LoaderFunctionArgs) => {
  const url = new URL(request.url);


  return {
    orders: await prisma.order.findMany({
      where: { shop: url.searchParams.get("shop") ?? undefined },
    }),
  };
};
```

***

## How to fix

Complete the verification appropriate to the entry point before protected operations, and stop those operations when verification fails.

For more detail, see [Authentication and authorization](https://shopify.dev/docs/apps/auth).

## app/routes/app.orders.tsx

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


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


export const loader = async ({ request }: LoaderFunctionArgs) => {
  // Await the barrier before touching any shop data. An un-awaited
  // authenticate.admin(request) is still flagged: the query races
  // it.
  const { session } = await authenticate.admin(request);


  return {
    orders: await prisma.order.findMany({ where: { shop: session.shop } }),
  };
};
```

***

## Related

* [`shopify app security check`](https://shopify.dev/docs/api/shopify-cli/app/app-security-check), the command that runs this check
* [All app security checks](https://shopify.dev/docs/apps/build/security/app-security-checks)

***
