Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No documentation for custom apps #719

Open
david-256 opened this issue Mar 27, 2024 · 14 comments
Open

No documentation for custom apps #719

david-256 opened this issue Mar 27, 2024 · 14 comments

Comments

@david-256
Copy link

david-256 commented Mar 27, 2024

Overview/summary

I want my Shopify app to be only installable by a certain merchant. I already set the distribution method to "custom distribution" within the partner dashboard.

If someone opens the domain on which my app is running in the browser, this person can install the app on his own store. This is unexpected behavior, since I specified within the Shopify partner dashboard that only a specific shop should be allowed to install my app.

I suppose the problem is that the Shopify config file shopify.server.ts by default is configured for distribution via the app store. I suppose that the following changes need to be carried out on my site:

  • Change distribution: AppDistribution.AppStore to either distribution: AppDistribution.ShopifyAdmin or distribution: AppDistribution.SingleMerchant.
  • Set a SHOP_CUSTOM_DOMAIN within my .env file

What Shopify can improve

My main problem is that I found no documentation on how to adjust the shopify.server.ts file for a custom app.

I don't know the difference between AppDistribution.ShopifyAdmin and AppDistribution.SingleMerchant. There is no documentation as doc comment within the code.

I don't know the effects of setting customShopDomains. There is no documentation as doc comment within the code.

Could you please clarify what I should do and also adjust the docs on https://shopify.dev as well as within the code.

Further information

I use the Shopify Remix app template.

In my app, the package @shopify/shopify-app-remix has the version 2.6.1.

Here is an excerpt from the default shopify.server.ts file (which I am currently using):

const shopify = shopifyApp({
  apiKey: process.env.SHOPIFY_API_KEY,
  apiSecretKey: process.env.SHOPIFY_API_SECRET || "",
  apiVersion: LATEST_API_VERSION,
  scopes: process.env.SCOPES?.split(","),
  appUrl: process.env.SHOPIFY_APP_URL || "",
  authPathPrefix: "/auth",
  sessionStorage: new PrismaSessionStorage(prisma),
  distribution: AppDistribution.AppStore,
  restResources,
  webhooks: {
    APP_UNINSTALLED: {
      deliveryMethod: DeliveryMethod.Http,
      callbackUrl: "/webhooks",
    },
  },
  hooks: {
    afterAuth: async ({ session }) => {
      shopify.registerWebhooks({ session });
    },
  },
  future: {
    v3_webhookAdminContext: true,
    v3_authenticatePublic: true,
    unstable_newEmbeddedAuthStrategy: true,
  },
  ...(process.env.SHOP_CUSTOM_DOMAIN
    ? { customShopDomains: [process.env.SHOP_CUSTOM_DOMAIN] }
    : {}),
});
@paulomarg
Copy link
Contributor

Hey, thanks for bringing this up. We're planning on going over all of our documentation from a custom app lens and revamp it, and this is great feedback, thank you! We'll keep this in mind when doing that and improve our docs!

In the meantime, some info on custom app distribution (full info in the docs):

  • ShopifyAdmin is for apps created by the merchant via the Shopify admin. You can't install these apps anywhere - they belong solely to that one shop
  • SingleMerchant is a partner-created app that can be installed by a merchant, which I believe is your scenario. When setting up this distribution in your partners dashboard, you'll be asked to provide a shop domain (or multiple plus domains) - that will create an install link that only those stores can use

Therefore, I think the solution for you is:

  • Set distribution to SingleMerchant
  • Go into partners dashboard and set up your app's distribution (the CLI can't do that for you AFAIK)

Hope this helps!

@lukeclifton
Copy link

Hey. I have just come across this same confusion and had to hunt around for a while to find this issue.

+1 for better docs around this!!

Also, for me the terms ShopifyAdmin and SingleMerchant are very confusing. The description for ShopifyAdmin distribution type sounds like it should be for SingleMerchant type.

@lukeclifton
Copy link

Also, when using SingleMerchant do we still need to set SHOP_CUSTOM_DOMAIN env var?

@lukeclifton
Copy link

Seeing something strange here...

I have set distribution to SingleMerchant in shopify.server.ts and set distribution type to "custom" in app settings however, I am still able to install the app on any Shopify store? Am I missing something?

@paulomarg
Copy link
Contributor

paulomarg commented Apr 16, 2024

Hey @lukeclifton - yeah, I agree the types of custom apps can be a bit confusing. Just to clarify: SingleMerchant apps work like app store apps as far as authentication goes.

You still need to go through the process of generating access tokens via OAuth (or token exchange) because they can be installed on multiple stores for Plus merchants, so they're not always tied to a single store, but to a single merchant. ShopifyAdmin apps are tied to a single store because they're created inside the context of that store's admin.

I think you have a good point in that these names are confusing. I wonder if we should change our distribution enum to have values:

  • AppDistribution.Public (current AppStore)
  • AppDistribution.Custom (current SingleMerchant)
  • AppDistribution.ShopifyAdmin

That feels like it might be clearer because it would match the docs.

I have set distribution to SingleMerchant in shopify.server.ts and set distribution type to "custom" in app settings however, I am still able to install the app on any Shopify store? Am I missing something?

When you set your app to custom distribution, you'd pick a store to install it to, right? Are you still able to login to other stores after doing that? IIRC Shopify should block you from authenticating with other stores.

@lukeclifton
Copy link

lukeclifton commented Apr 16, 2024

Hey @paulomarg Thanks for coming back so quick!

Yeah I much prefer the use of terms "Public" and "Custom" as these are terms we already use and are familiar with.

The term "ShopifyAdmin" still throws me off to be honest. Using the old term "Private" seems way more obvious but perhaps something like "Manual" is an idea? Or "SingleStore" if your sticking with "SingleMerchant".

When you set your app to custom distribution, you'd pick a store to install it to, right? Are you still able to login to other stores after doing that? IIRC Shopify should block you from authenticating with other stores.

Yes, to confirm I am setting app to custom distribution and setting a store to install too which cannot be changed as expected. Then when I try and install on a completely different store owned by a different partner account I am still able to install the app without any restrictions. 😕

I remember when Shopify blocked this also and that's what I am expecting. Is this a bug? If not, how do we lock custom apps down to just a single merchant?

@paulomarg
Copy link
Contributor

We'll look into the naming when we make the changes for custom apps, thanks!

As for the bug, I've reported it to the team and they're looking into it - it may be that you can install your custom app in multiple "Non-transferable" stores, but Shopify will still block installs for merchants other than the one you assigned when you configured the app.

@lukeclifton
Copy link

lukeclifton commented Apr 17, 2024

OK thanks for looking into it. Yeah I think the store I tested with was a "Non-transferable" however I see this as a issue.
You shouldn't be able to install a custom app for another merchant regards if its a dev store or not. Seems a bit of a security flaw if the app is not meant to be public facing.

So currently we will need to implement some custom backend auth logic to restrict install to only whitelisted store domains?

@paulomarg
Copy link
Contributor

I followed up with the team and they're looking into it, but one thing to notice is that you can only install such apps if you have the link to begin with, and this would only have any impact on development stores (that have several restrictions compared to "regular" stores), which should mitigate that risk.

Thanks for bringing that up :)

@david-256
Copy link
Author

Hey @paulomarg, please check out my HackerOne report with the report id 2445815. Unfortunately, it has been categorized as a functional problem, but I believe it is a security issue. In this report, I have written down a step-by-step guide to install a custom app of a different merchant without having access to the installation link. I hope this issue gets fixed.

@lukeclifton
Copy link

Yeah with the current Remix app template, you could install an app without having a Shopify app install URL. You would just need to know the app URL and then you could go to the /auth route and add a Shopify domain.

Here's a real world example:
A developer is building an internal management app for an enterprise merchant. This app connects to external business related API's and should never be able to be accessed by someone external to the company.

If a developer builds such a custom app and uses the distribution type SingleMerchant they may think this is safe, however in reality someone with knowledge of the app URL, could install the app on a development store and access something they shouldn't be able to see.

@paulomarg
Copy link
Contributor

paulomarg commented Apr 19, 2024

Fair points, thank you folks. I'm forwarding that to the team that manages this area :)

@lukeclifton
Copy link

@paulomarg What do you think to adding a "store domain whitelist" config feature to the app template to overcome this issue?

@zzooeeyy
Copy link
Contributor

Hello!

We’re sorry to hear about your frustrations regarding app installations. Our team has reviewed this issue and found that allowing apps to be installed on other development stores provides greater flexibility and benefit for app developers. As for the potential security concern that was pointed out, we have restrictions in place to ensure custom apps can only be installed on other non-transferrable development stores, and apps should ensure access and sensitive data is gated for a particular session. We agree that it’s definitely causing confusion, so we will update the documentation and wording on this.

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants