---
title: Shop domain validation regex is not anchored
description: >-
  Detects unanchored `myshopify.com` regexes that allow domain spoofing and
  token theft.
source_url:
  html: >-
    https://shopify.dev/docs/apps/build/security/app-security-checks/weak-shop-validation
  md: >-
    https://shopify.dev/docs/apps/build/security/app-security-checks/weak-shop-validation.md
---

# Shop domain validation regex is not anchored

Detects unanchored `myshopify.com` regexes that allow domain spoofing and token theft.

| Detail | Value |
| - | - |
| Check ID | `WEAK_SHOP_VALIDATION` |
| Severity | High |
| How it runs | Agent review |

***

## Vulnerable example

## app/utils/shop.server.ts

```ts
// Unanchored: "evil.com/x.myshopify.com" and
// "shop.myshopify.com.evil.test" both match, so a forged shop
// value passes validation and reaches token lookup.
const SHOP_PATTERN = /[a-zA-Z0-9-]+\.myshopify\.com/;


export function isValidShop(shop: string) {
  return SHOP_PATTERN.test(shop);
}
```

***

## How to fix

Anchor the regex with `^` and `$` to prevent prefix/suffix attacks.

For more detail, see [Authorization code grant](https://shopify.dev/docs/apps/build/authentication-authorization/access-tokens#authorization-code-grant).

## app/utils/shop.server.ts

```ts
// Anchored at both ends, so the whole string has to be the shop
// domain.
const SHOP_PATTERN = /^[a-zA-Z0-9][a-zA-Z0-9-]*\.myshopify\.com$/;


export function isValidShop(shop: string) {
  return SHOP_PATTERN.test(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)

***
